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

SpringBoot 项目实现操作日志的记录(使用 AOP 注解模式)


本文是博主在做关于如何记录用户操作日志时做的记录,常见的项目中难免存在一些需要记录重要日志的部分,例如权限和角色设定,重要数据的操作等部分。

博主使用 Spring 中的 AOP 功能,结合注解的方式,对用户操作过的一些重要方法做日志记录,存储到数据库中,可以随时查阅。

本文使用技术:SpringBoot 3 + JDK17 + MyBatis-Plus + MySQL。


文章目录

    • 01、PostMan 测试结果
    • 02、数据库存储数据后展示样式
    • 03、数据库表创建语句
    • 04、项目结构图
    • 05、代码:application.yml
    • 06、代码:pom.xml
    • 07、代码:注解 LogRecord
    • 08、代码:LogRecordAop
    • 09、代码:OperateTypeEnum
    • 10、代码:TestController
    • 11、代码:LogRecordMapper(使用 MyBatis-Plus)
    • 12、代码:ProjectLog(实体类)
    • 13、代码:UserInfo
    • 14、代码:UserServiceImpl
    • 15、代码:IUserService
    • 16、代码:LogAopUtils
    • 17、代码:LogHolder
    • 18、代码:UserHolder
    • 19、代码:Application
    • 20、代码:LogRecordMapper.xml

01、PostMan 测试结果

青灯文案-测试

02、数据库存储数据后展示样式

在这里插入图片描述

03、数据库表创建语句

CREATE TABLE project_log (id bigint(20) NOT NULL AUTO_INCREMENT COMMENT '日志ID',company_id varchar(36) DEFAULT NULL COMMENT '公司ID',company varchar(200) DEFAULT NULL COMMENT '公司',uname varchar(100) DEFAULT NULL COMMENT '用户名',uid bigint(20) DEFAULT NULL COMMENT '用户ID',operate_type int(10) DEFAULT NULL COMMENT '操作类型',operate_module varchar(64) DEFAULT NULL COMMENT '操作模块',operate_desc varchar(255) DEFAULT NULL COMMENT '操作描述',operate_param text DEFAULT NULL COMMENT '操作参数',operate_time bigint(20) DEFAULT NULL COMMENT '操作时间',operate_result tinyint(10) DEFAULT NULL COMMENT '操作结果',PRIMARY KEY (id)
);create index idx_operate_typeon project_log (operate_type);create index idx_operate_moduleon project_log (operate_module);create index idx_uidon project_log (uid);create index idx_companyon project_log (company);create index idx_unameon project_log (uname);

04、项目结构图

青灯文案-项目结构

05、代码:application.yml

server:port: 8089spring:datasource:url: jdbc:mysql://10.100.4.163:3306/test?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghaidriver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: 123456

06、代码:pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.wen</groupId><artifactId>Test-Operate-Log</artifactId><version>1.0-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.4.1</version><relativePath/> <!-- lookup parent from repository --></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-jsqlparser</artifactId><version>3.5.9</version></dependency><!--mybatis--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.9</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-core</artifactId><version>1.3.5</version><scope>test</scope></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId></dependency><dependency><groupId>com.fhs-opensource</groupId><artifactId>easy-trans-mybatis-plus-extend</artifactId><version>3.0.6</version></dependency><dependency><groupId>com.oracle.database.jdbc</groupId><artifactId>ojdbc8</artifactId></dependency><dependency><groupId>org.mybatis.dynamic-sql</groupId><artifactId>mybatis-dynamic-sql</artifactId><version>1.4.0</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.1</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.83</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><configuration><archive><!--生成的jar 不要包含pom.xml pom.properties 这2个文件--><addMavenDescriptor>false</addMavenDescriptor><manifest><!--是否要不第三番jar放到manifest的classpath中--><addClasspath>true</addClasspath><!--生成的manifest中的classpath的前缀,因为要把第三方jar放到lib目录下,所以classpath前缀是lib/--><classpathPrefix>lib/</classpathPrefix><!--应用的main class --><mainClass>cn.com.wind.server.Application</mainClass></manifest></archive></configuration></plugin></plugins></build></project>

07、代码:注解 LogRecord

package com.wen.common;import com.wen.common.OperateTypeEnum;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** @author : rjw* @date : 2025-05-19*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogRecord {OperateTypeEnum operateType() default OperateTypeEnum.OTHER;
}

08、代码:LogRecordAop

package com.wen.common;import cn.hutool.core.util.ArrayUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wen.mapper.LogRecordMapper;
import com.wen.model.UserInfo;
import com.wen.model.ProjectLog;
import com.wen.service.IUserService;
import com.wen.utils.LogAopUtils;
import com.wen.utils.LogHolder;
import com.wen.utils.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.util.Arrays;/*** @author : rjw* @date : 2025-05-07*/
@Aspect
@Component
@Slf4j
public class LogRecordAop {@Autowiredprivate IUserService userService;@Autowiredprivate LogRecordMapper logRecordMapper;/*** 切入点 使用注解路径*/@Pointcut("@annotation(com.wen.common.LogRecord)")public void record() {}/*** 前置操作* @param point 切入点*/@Before("record() && @annotation(logRecord)")public void before(JoinPoint point, LogRecord logRecord) {ProjectLog logInfo = new ProjectLog();UserInfo user = UserHolder.getCurrentUser();// id 自增if (user != null) {logInfo.setUid(user.getUid());logInfo.setUname(user.getName());logInfo.setCompanyId(user.getCompanyId() == null ? "" : user.getCompanyId());logInfo.setCompany(user.getCompany());} else {// 如果为null,则说明开发人员使用接口调用logInfo.setUid(-1L);logInfo.setUname("开发人员");logInfo.setCompanyId("");logInfo.setCompany("tx");}logInfo.setOperateType(logRecord.operateType().getCode());logInfo.setOperateModule(logRecord.operateType().getModule());logInfo.setOperateTime(System.currentTimeMillis());Object[] args = LogAopUtils.removeUnnecessaryArgs(point.getArgs());logInfo.setOperateDesc(genOperateDesc(logRecord.operateType(), args, logInfo));if (ArrayUtil.isNotEmpty(args)) {if (logRecord.operateType() == OperateTypeEnum.EXPORT) {logInfo.setOperateParam(JSON.toJSONString(args[0]));} else {logInfo.setOperateParam(JSON.toJSONString(args));}}LogHolder.setProjectLog(logInfo);}private String genOperateDesc(OperateTypeEnum operateType, Object[] args, ProjectLog projectLog) {String operateDesc = String.format("【%s】-%s", operateType.getModule(), operateType.getFunction());if (ArrayUtil.isEmpty(args)) {return operateDesc;}switch (operateType) {case OPERATE:operateDesc = String.format(operateDesc, Arrays.toString(args));break;default:JSONObject req = JSONObject.parseObject(JSON.toJSONString(args[0]));operateDesc = String.format(operateDesc, req.toJSONString());break;}log.info("operateDesc: {}", operateDesc);return operateDesc;}@AfterReturning(value = "record()", returning = "response")public void afterReturning(Object response) {try {ProjectLog logInfo = LogHolder.getProjectLog();//   ======== 这里要求要使用返回值   if (logInfo == null || response == null) {return;}logInfo.setOperateResult((byte) 400);if (!checkParam(logInfo)) {log.warn("add log to DB failed cause param error! complianceLog:{}", logInfo);return;}addPrivateQuoteLog(logInfo);} finally {LogHolder.removeProjectLog();}}@AfterThrowing(value = "record()", throwing = "t")public void afterThrowing(Throwable t) {try {ProjectLog infoLog = LogHolder.getProjectLog();if (infoLog == null) {return;}infoLog.setOperateResult((byte) 400);if (!checkParam(infoLog)) {log.warn("add log to DB failed cause param error! complianceLog:{}", infoLog);return;}addPrivateQuoteLog(infoLog);} finally {LogHolder.getProjectLog();}}@Asyncprivate void addPrivateQuoteLog(ProjectLog projectLog) {logRecordMapper.insert(projectLog);}private boolean checkParam(ProjectLog projectLog) {return projectLog != null &&projectLog.getCompanyId() != null &&projectLog.getCompany() != null &&projectLog.getUid() != null &&projectLog.getOperateResult() != null &&projectLog.getOperateTime() != null &&projectLog.getOperateType() != null &&projectLog.getUname() != null;}
}

09、代码:OperateTypeEnum

package com.wen.common;import lombok.Getter;/*** @author : rjw* @date : 2025-05-19*/
@Getter
public enum OperateTypeEnum {OTHER(0, "系统","其它类型"),OPERATE(1, "内部接口—操作", "操作"),EXPORT(2, "内部接口—导出", "导出"),MAX(100, "", "");private final int code;private final String module;private final String function;OperateTypeEnum(int code, String module, String function) {this.code = code;this.module = module;this.function = function;}
}

10、代码:TestController

package com.wen.controller;import com.wen.common.LogRecord;
import com.wen.common.OperateTypeEnum;
import com.wen.model.UserInfo;
import com.wen.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;/*** @author : rjw* @date : 2025-05-19*/
@Slf4j
@RestController
@RequestMapping("/system")
public class TestController {@Autowiredprivate IUserService userService;@GetMapping("/testLog")@LogRecord(operateType = OperateTypeEnum.OPERATE)public UserInfo updateQuoteChannelPush(@RequestParam("id") long id, @RequestParam("name") String name,@RequestParam("company") String company, @RequestParam("companyId") String companyId) {userService.getCurrentUser();// 和内部数据无关UserInfo userInfo = new UserInfo();userInfo.setUid(id);userInfo.setName(name);userInfo.setCompany(company);userInfo.setCompanyId(companyId);log.info("userInfo is {}", userInfo);// 要有返回值,不然不能记录,可以在AOP中自己调return userInfo;}
}

11、代码:LogRecordMapper(使用 MyBatis-Plus)

package com.wen.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wen.model.ProjectLog;/*** @author : rjw* @date : 2025-05-19*/
public interface LogRecordMapper extends BaseMapper<ProjectLog> {}

12、代码:ProjectLog(实体类)

package com.wen.model;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;/*** @author : rjw* @date : 2025-05-19*/
@Data
@TableName("project_log")
public class ProjectLog {/*** 日志 ID*/@TableId(value = "id", type = IdType.AUTO)private Long logId;/*** 公司ID*/private String companyId;/*** 公司*/private String company;/*** 用户名*/private String uname;/*** 用户ID*/private Long uid;/*** 操作类型*/private Integer operateType;/*** 操作模块*/private String operateModule;/*** 操作描述*/private String operateDesc;/*** 操作参数*/private String operateParam;/*** 操作时间*/private Long operateTime;/*** 操作结果*/private Byte operateResult;
}

13、代码:UserInfo

package com.wen.model;import lombok.Data;/*** @author : rjw* @date : 2025-05-19*/
@Data
public class UserInfo {private long uid;private String name;private String company;private String companyId;
}

14、代码:UserServiceImpl

package com.wen.service.impl;import com.wen.model.UserInfo;
import com.wen.service.IUserService;
import com.wen.utils.UserHolder;
import org.springframework.stereotype.Service;/*** @author : rjw* @date : 2025-05-19*/
@Service
public class UserServiceImpl implements IUserService {@Overridepublic UserInfo getCurrentUser() {/*** 一般是登陆的时候设置当前用户* 下线的时候删除当前用户*/UserInfo userInfo = new UserInfo();userInfo.setUid(1000001);userInfo.setName("张三");userInfo.setCompany("tx");userInfo.setCompanyId("tx");UserHolder.setCurrentUser(userInfo);return userInfo;}
}

15、代码:IUserService

package com.wen.service;import com.wen.model.UserInfo;/*** @author : rjw* @date : 2025-05-19*/
public interface IUserService {UserInfo getCurrentUser();}

16、代码:LogAopUtils

package com.wen.utils;import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.catalina.connector.RequestFacade;
import org.apache.catalina.connector.ResponseFacade;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;public class LogAopUtils {public final static Set<Class<?>> UNNECESSARY_CLASS = new HashSet<Class<?>>(){{add(ServletRequest.class);add(ServletResponse.class);add(HttpServletRequest.class);add(HttpServletResponse.class);add(RequestFacade.class);add(ResponseFacade.class);}};public final static Set<Class<?>> UNNECESSARY_SUPER_CLASSES = new HashSet<Class<?>>() {{add(MultipartFile.class);}};public static Object[] removeUnnecessaryArgs(Object[] args) {List<Object> list = new ArrayList<>();outer: for (Object arg : args) {if (UNNECESSARY_CLASS.contains(arg.getClass())) {continue;}for (Class<?> superClass : UNNECESSARY_SUPER_CLASSES) {if(superClass.isAssignableFrom(arg.getClass())) {continue outer;}}list.add(arg);}return list.toArray();}
}

17、代码:LogHolder

package com.wen.utils;import com.wen.model.ProjectLog;public class LogHolder {private static final ThreadLocal<ProjectLog> LOCAL_PROJECT_LOG = new ThreadLocal<>();public static ProjectLog getProjectLog() {return LOCAL_PROJECT_LOG.get();}public static void setProjectLog(ProjectLog user) {LOCAL_PROJECT_LOG.set(user);}public static void removeProjectLog() {LOCAL_PROJECT_LOG.remove();}
}

18、代码:UserHolder

package com.wen.utils;import com.wen.model.UserInfo;/*** @author : rjw* @date : 2025-05-07*/
public class UserHolder {private static final ThreadLocal<UserInfo> CURRENT_USER = new ThreadLocal<>();public static UserInfo getCurrentUser() {return CURRENT_USER.get();}public static void setCurrentUser(UserInfo user) {CURRENT_USER.set(user);}public static void removeCurrentUser() {CURRENT_USER.remove();}
}

19、代码:Application

package com.wen;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** @author : rjw* @date : 2025-05-19*/
@SpringBootApplication
@MapperScan(basePackages = {"com.wen.mapper"})
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class);}
}

20、代码:LogRecordMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wen.mapper.LogRecordMapper"></mapper>

相关文章:

SpringBoot 项目实现操作日志的记录(使用 AOP 注解模式)

本文是博主在做关于如何记录用户操作日志时做的记录&#xff0c;常见的项目中难免存在一些需要记录重要日志的部分&#xff0c;例如权限和角色设定&#xff0c;重要数据的操作等部分。 博主使用 Spring 中的 AOP 功能&#xff0c;结合注解的方式&#xff0c;对用户操作过的一些…...

C/C++ 整数类型的长度

参考 cppreference.cn 在某些语言中&#xff0c;整数类型的长度是固定的&#xff0c;如java中 char 8short 16int 32long 64 可是C/C 与机器相关&#xff0c;整数类型长度与平台有关 先可以记一个简单的 按照C标准&#xff1a; char > 8short > 16int > 16long &g…...

解决npm install报错:getaddrinfo ENOTFOUND registry.nlark.com

问题背景 在使用 npm install 安装依赖时&#xff0c;突然遇到以下错误&#xff1a; npm ERR! network request to https://registry.nlark.com/fsevents/download/fsevents-2.3.2.tgz failed, reason: getaddrinfo ENOTFOUND registry.nlark.com这表明 npm 在尝试从 registr…...

PostgreSQL简介安装

目录 一. PostgreSQL 1. 简介 2. 特点 3. 优势 4. 架构 5. 应用场景 二. 安装PostgerSQL 1. 编译安装 (1) 安装编译安装所需环境 (2) 编译安装 (3) 配置环境变量 (4) 登录数据库 2. DNF安装 (1) 安装postgreSQL (2) 初始化数据库 (3) 登录数据库 三. postgreSQ…...

vue3+elementPlus穿梭框拖拽

安装 npm install sortablejs --save <template><div class"transfer" ref"transfer"><div><el-transfer v-model"inputForm" :data"data" :titles"titles"><template #default"{ option }…...

牛客周赛 Round 93题解(个人向A-E)

牛客周赛 Round 93题解&#xff08;个人向A-E&#xff09; 题目链接&#xff1a;https://ac.nowcoder.com/acm/contest/109904 a题 签到题&#xff0c;直接按题意模拟即可 #include <bits/stdc.h> using namespace std; #define ll long long int main() {ios::sync_…...

MySQL高可用之ProxySQL + MGR 实现读写分离实战

部署MGR 1、MGR 前置介绍 阿里云RDS集群方案用的就是MGR模式&#xff01; 1.1、什么是 MGR MGR&#xff08;MySQL Group Replication&#xff09;是MySQL 5.7.17版本诞生的&#xff0c;是MySQL自带的一个插件&#xff0c;可以灵活部署。保证数据一致性又可以自动切换&#x…...

React TS中如何化简DOM事件的定义

概要 我们在做TS开发时候&#xff0c;总要面对各种类型的定义。React使用自己的Sythetic Event机制管理DOM事件&#xff0c;不同于原生的DOM事件定义&#xff0c;所以在TS中&#xff0c;事件的类型定义更加繁琐。 本文提供一中简化定义的方法&#xff0c;在使用中&#xff0c…...

BigemapPro蒙版使用技巧:精准导出地图范围

在地图制图过程中&#xff0c;我们常常会遇到需要按照特定边界裁剪地图&#xff0c;或者对指定范围以外的地图进行模糊处理等情况&#xff0c;这时"添加蒙版"功能就非常实用。 BigemapPro的蒙版功能&#xff0c;可满足用户按自定义形状裁剪地图、控制区域外显示效果&…...

CesiumEarth v1.15 更新

更新&#xff1a;​ CesiumEarth 更新至1.15.0版本&#xff0c;包含浏览器在线版、Desktop Windows版本、Desktop 安卓版本 界面优化&#xff1a;​ 项目列表已适配手机屏幕 功能​ 扩展模块更新 1、在底部工具栏区域&#xff0c;所有已生效&#xff08;已勾选&#xff0…...

SOC-ESP32S3部分:2-2-VSCode进行编译烧录

飞书文档https://x509p6c8to.feishu.cn/wiki/CTzVw8p4LiaetykurbTciA42nBf?fromScenespaceOverview 无论是使用Window搭建IDF开发环境&#xff0c;还是使用Linux Ubuntu搭建IDF开发环境&#xff0c;我们都建议使用VSCode进行代码编写和编译&#xff0c;VSCode界面友好&#x…...

机器学习 day05

文章目录 前言一、模型选择与调优1.交叉验证2.超参数搜索 前言 通过今天的学习&#xff0c;我掌握了机器学习中模型的选择与调优&#xff0c;包括交叉验证&#xff0c;超参数搜索的概念与基本用法。 一、模型选择与调优 模型的选择与调优有许多方法&#xff0c;这里主要介绍较…...

关于element-ui的table type=“expand“ 嵌套表格展开异常问题解决方案

也许是很久没用这个库了 今天找这个问题还花了一会儿时间 也是蛮简单的一个问题 排查过程就不说了 直接说结果吧 记录一下 发现问题 展开第一列的时候表格没问题 收起的时候 莫名其妙多了一个展开的按钮 代码咋一看没什么问题 百思不解不得其解 甚至怀疑row-key的问题 检查了数…...

Pichome 开源网盘程序index.php 文件读取漏洞(CVE-2025-1743)

免责声明 本文档所述漏洞详情及复现方法仅限用于合法授权的安全研究和学术教育用途。任何个人或组织不得利用本文内容从事未经许可的渗透测试、网络攻击或其他违法行为。使用者应确保其行为符合相关法律法规,并取得目标系统的明确授权。 对于因不当使用本文信息而造成的任何直…...

[SpringBoot]Spring MVC(6.0)----图书管理系统(初)

图书管理系统 需求: 1. 登录: 用户输入账号,密码完成登录功能. 2. 列表展示: 展示图书. 准备工作 将前端代码复制到 static 目录下. 约定前后端交互接口 两个功能: 用户登录 和 图书列表展示. 需求分析: 1. 用户登录 url : /user/login param : userName 和 password return …...

C语言:基础篇之常见概念

文章目录 1.C语言是什么&#xff1f;2.C语言的历史和辉煌3.编译器的选择VS20223.1 编译和链接3.2 编译器的对比3.3 VS2022 的优缺点 4.VS项目和源文件、头文件介绍5.第一个C语言程序6.main函数7.printf和库函数8.关键字介绍9.字符和ASCII编码10.字符串和\011.转义字符12.语句和…...

Ansible模块——管理100台Linux的最佳实践

使用 Ansible 管理 100 台 Linux 服务器时&#xff0c;推荐遵循以下 最佳实践&#xff0c;以提升可维护性、可扩展性和安全性。以下内容结合实战经验进行总结&#xff0c;适用于中大型环境&#xff08;如 100 台服务器&#xff09;&#xff1a; 一、基础架构设计 1. 分组与分层…...

算法与数据结构:质数、互质判定和裴蜀定理

文章目录 质数质数判定质数筛选质因数分解互质判定裴蜀定理 质数 首先回顾「质数」的定义&#xff1a;若一个正整数无法被除了 1 ​和它自身之外的任何自然数整除&#xff0c;则称该数为质数&#xff08;或素数&#xff09;&#xff0c;否则称该正整数为合数。 根据上述定义&…...

基于C#的Modbus通信协议全面解析与实现指南

目录 1. Modbus协议概述 1.1 Modbus网络结构 1.2 Modbus功能码 2. Modbus RTU模式实现 2.1 RTU模式特点 2.2 CRC-16校验算法 2.3 使用NModbus4库实现RTU通信 3. Modbus TCP/IP模式实现 3.1 TCP模式特点 3.2 MBAP报文头结构 3.3 使用NModbus实现TCP通信 3.4 原生TCP套…...

IVX:重构 AI 原生开发范式,让模型调用成为指尖艺术​

一、AI 原生开发的技术跃迁&#xff1a;从黑箱集成到白盒重构 在传统 AI 开发范式中&#xff0c;将 GPT-4o、Mediapipe 等模型集成到业务系统往往需要经历 "模型训练 - API 对接 - 前端适配" 的复杂流程。开发团队需同时掌握机器学习框架&#xff08;如 TensorFlow&…...

源码分析之Leaflet中TileLayer

概述 TileLayer 是 Layer 的子类&#xff0c;继承自GridLayer基类&#xff0c;用于加载和显示瓦片地图。它提供了加载和显示瓦片地图的功能&#xff0c;支持自定义瓦片的 URL 格式和参数。 源码分析 源码实现 TileLayer的源码实现如下&#xff1a; export var TileLayer …...

Java虚拟机 - 程序计数器和虚拟机栈

运行时数据结构 Java运行时数据区程序计数器为什么需要程序计数器执行流程虚拟机栈虚拟机栈作用虚拟机栈核心结构运行机制 Java运行时数据区 首先介绍Java运行时数据之前&#xff0c;我们要了解&#xff0c;对于计算机来说&#xff0c;内存是非常重要的资源&#xff0c;因为内…...

大语言模型 15 - Manus 超强智能体 开源版本 OpenManus 案例与原理深入解析

写在前面 Manus 是由中国初创公司 Monica.im 于 2025 年 3 月推出的全球首款通用型 AI 智能体&#xff08;AI Agent&#xff09;&#xff0c;旨在实现“知行合一”&#xff0c;即不仅具备强大的语言理解和推理能力&#xff0c;还能自主执行复杂任务&#xff0c;直接交付完整成…...

开源CMS系统中哪些常见的安全漏洞最需要注意?

在当今数字化时代&#xff0c;开源内容管理系统&#xff08;CMS&#xff09;因其灵活性和低成本广受欢迎。然而&#xff0c;开源CMS的安全漏洞也频频成为黑客攻击的突破口。本文将带大家全面了解下开源CMS中需要警惕的安全漏洞以及防护建议&#xff0c;以帮助开发者和管理员更好…...

文件包含靶场实现

文件包含漏洞&#xff08;File Inclusion Vulnerability&#xff09;是 Web 安全中常见的高危漏洞&#xff0c;主要分为 本地文件包含&#xff08;LFI&#xff09; 和 远程文件包含&#xff08;RFI&#xff09; 1、典型利用方式 利用方式示例 Payload说明路径遍历?page../../…...

在 JavaScript 中正确使用 Elasticsearch,第二部分

作者&#xff1a;来自 Elastic Jeffrey Rengifo 回顾生产环境中的最佳实践&#xff0c;并讲解如何在无服务器环境中运行 Elasticsearch Node.js 客户端。 想获得 Elastic 认证&#xff1f;查看下一期 Elasticsearch Engineer 培训的时间&#xff01; Elasticsearch 拥有大量新…...

DataLight(V1.7.12)版本更新发布

DataLight&#xff08;V1.7.12&#xff09;版本更新发布 亲爱的 DataLight 用户们&#xff0c; DataLight 发布 V1.7.12 版本&#xff0c;此版本带来了新服务 DINKY 的支持&#xff0c;以及多项问题修复&#xff0c;进一步提升了平台的易用性和稳定性。 一. 更新日志 在此次…...

LeetCode-前缀和-和为K的子数组

LeetCode-前缀和-和为K的子数组 ✏️ 关于专栏&#xff1a;专栏用于记录 prepare for the coding test。 文章目录 LeetCode-前缀和-和为K的子数组&#x1f4dd; 和为K的子数组&#x1f3af;题目描述&#x1f50d; 输入输出示例&#x1f9e9;题目提示&#x1f9ea;前缀和❓什么…...

MySQL基础关键_014_MySQL 练习题

目 录 一、有以下表&#xff0c;请用一条 SQL 语句查询出每门课程都大于 80 分的学生 二、综合题1&#xff08;数据自行模拟&#xff09; 1.查询身份证号为“440401430103082”的申请日期 2.查询同一个身份证号有两条及以上记录的身份证号码及记录个数 3.将身份证号码为“4…...

femap许可与云计算集成

随着云计算技术的迅猛发展&#xff0c;越来越多的企业开始将关键应用和服务迁移到云端&#xff0c;以享受其带来的弹性扩展、高效管理和成本优化等优势。Femap作为一款强大的电磁仿真工具&#xff0c;通过与云计算的集成&#xff0c;将为企业带来前所未有的许可管理和仿真分析体…...

uni-app项目从0-1基础架构搭建全流程

前情 最近新接了一个全新项目&#xff0c;我负责从0开始搭建小程序&#xff0c;我选用的技术栈是uni-app技术栈&#xff0c;UI库选择的是uview-plus&#xff0c;CSS引入现在流行的tainlwindcss&#xff0c;实现CSS原子化书写&#xff0c;实现小程序分包&#xff0c;分包中实现…...

轻量级高性能推理引擎MNN 学习笔记 04.线性回归

1. 线性回归 MNN 官方给的iOS Demo中&#xff0c;输入是图片&#xff0c;输出是分类结果&#xff0c;相对来讲&#xff0c;略微有些复杂&#xff0c;我们现在用一个最简单的线性回归模型&#xff0c;来说明MNN的用法。 该线性回归是yaxb &#xff08;其中a2,b0.01&#xff09…...

使用 React PDF 构建 React.js PDF 查看器的指南

在本文中&#xff0c;我们将重点介绍在React.js中制作 PDF 查看器的最受欢迎的开源库。具体来说&#xff0c;我们将利用著名的开源库react-pdf的功能&#xff0c;指导您完成创建 React.js PDF 查看器的过程。 通过本教程&#xff0c;您将在第一部分学习如何使用 React-PDF 在 …...

动力电池点焊机厂家:驱动新能源制造的精密力量|比斯特自动化

在新能源汽车、储能系统等产业蓬勃发展的背景下&#xff0c;动力电池点焊机作为电池模组生产的核心设备&#xff0c;正经历着技术迭代与市场需求的双重升级。这类厂家通过持续研发与创新&#xff0c;不仅满足了电池制造企业对焊接精度、效率与稳定性的严苛要求&#xff0c;更推…...

React的合成事件(SyntheticEventt)

文章目录 前言 前言 React的合成事件&#xff08;SyntheticEvent&#xff09;是React为了统一不同浏览器的事件处理行为而封装的一套跨浏览器事件系统。它与原生事件的主要区别如下&#xff1a; 1. 事件绑定方式 • 合成事件&#xff1a;使用驼峰命名法绑定事件&#xff08;如…...

知识中台Top5:Baklib上榜推荐

Baklib知识中台优势 在数字化转型浪潮中&#xff0c;Baklib凭借其知识中台的核心设计理念&#xff0c;构建了企业级知识管理的差异化竞争力。区别于传统文档管理系统&#xff0c;该平台通过四库体系&#xff08;知识资源库、场景规则库、服务模型库、应用组件库&#xff09;实…...

在Windows系统中使用C++与Orthanc交互:基于DICOMweb的医学影像应用开发

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家、CSDN平台优质创作者&#xff0c;高级开发工程师&#xff0c;数学专业&#xff0c;10年以上C/C, C#, Java等多种编程语言开发经验&#xff0c;拥有高级工程师证书&#xff1b;擅长C/C、C#等开发语言&#xff0c;熟悉Java常用开…...

视频太大?用魔影工厂压缩并转MP4,画质不打折!

在日常生活中&#xff0c;我们常常需要将视频文件转换成不同的格式以适应各种设备或平台的播放需求。魔影工厂作为一款功能强大且操作简单的视频转换工具&#xff0c;深受用户喜爱。本文中简鹿办公将手把手教你如何使用魔影工厂将视频转换为MP4格式&#xff0c;并进行个性化设置…...

Wan2.1 通过首尾帧生成视频

Wan2.1 通过首尾帧生成视频 flyfish 使用 Wan2.1-FLF2V-14B-720P 模型&#xff0c;通过输入两张图像&#xff08;起始帧和结束帧&#xff09;&#xff0c;生成一段连贯的视频。 First Last Frame-to-Video 即 “首末帧到视频” 技术 import numpy as np import torch import…...

宝塔+fastadmin:给项目添加定时任务

一、定时任务脚本编写 1. 使用 shebang 声明执行器 #!/usr/bin/env php 这是 Unix/Linux 系统中脚本文件的标准开头。表示这个脚本使用系统环境变量中的 php 来执行。2. 定义 ThinkPHP 入口路径并加载框架 define(APP_PATH, __DIR__ . /../../application/); require __DIR__…...

[自动化集成] 使用明道云上传附件并在Python后端处理Excel的完整流程

在企业日常自动化场景中,使用低代码平台如明道云搭建前端界面,结合自定义Python后端服务,实现灵活数据处理是一种高效的组合方式。本文将分享一个典型的集成用例:用户通过明道云上传文本和Excel附件,Python后端接收并解析这些信息,最终实现完整的数据处理闭环。 项目背景…...

前端项目采用响式布局

要让整个前端项目采用响应式布局&#xff0c;可以从多个方面进行优化&#xff0c;以下是一些具体的建议和实现方法&#xff1a; 1. 使用 ElementPlus 的响应式特性 ElementPlus 组件库本身提供了一些响应式的能力&#xff0c;例如 el-col 组件可以用于创建响应式的网格布局。…...

【Unity】DOTween的常用函数解释

DOTween插件常用函数解释 1.DOTween.To&#xff08;通用变化动画&#xff09; 解释&#xff1a;将某一个值在一定的时间内变化到另一个值&#xff08;通用的函数&#xff09;&#xff0c;可用于大部分的动画变化 使用示例&#xff1a; using UnityEngine; using DG.Tweenin…...

飞桨paddle import fluid报错【已解决】

跟着飞桨的安装指南安装了paddle之后 pip install paddlepaddle有一个验证&#xff1a; import paddle.fluid as fluid fluid.install check.run check()报错情况如下&#xff0c;但是我在pip list中&#xff0c;确实看到了paddle安装上了 我import paddle别的包&#xff0c…...

ELK简介和docker版安装

使用场景 主要还是给开发人员“打捞日志”用的。 ELK 是由三个开源工具组成的套件&#xff08;Elasticsearch、Logstash 和 Kibana&#xff09;&#xff0c;主要用于日志的收集、分析和可视化。以下是 ELK 常见的使用场景&#xff1a; 日志集中化管理 收集来自多个服务器或服…...

DockerHub被封禁,怎么将镜像传到国内?一种简单合规的镜像同步到国内方案[最佳实践]

Docker将容器化技术普及&#xff0c;推动云计算向云原生的演进。Docker的核心创新技术之一是容器镜像&#xff0c;它是一种文件的打包方式&#xff0c;将应用程序运行的操作系统、库、运行环境等依赖全部打包一起。在其他任意环境&#xff0c;只要可以运行docker服务&#xff0…...

飞桨paddle ‘ParallelEnv‘ object has no attribute ‘_device_id‘【已解决】

书借上回&#xff0c;自从我反复重装paddle之后&#xff0c;我发现了&#xff0c;只要pip list中有库&#xff0c;但是代码报错&#xff0c;那就是飞桨没把代码更新完全&#xff0c;只能自己去改源代码 我又遇到报错了&#xff1a; 根据报错信息&#xff0c;找到ParallelEnv报…...

网络安全面试题(一)

文章目录 一、基础概念与模型‌1. 什么是通信协议&#xff1f;列举三种常见的网络通信模型&#xff1f;2. 解释OSI七层模型及各层功能3. TCP/IP四层模型与OSI模型的对应关系是什么&#xff1f;4. 五层协议体系结构与TCP/IP模型的区别?5. 什么是面向连接与非面向连接的服务&…...

【Leetcode 每日一题】3355. 零数组变换 I

问题背景 给定一个长度为 n n n 的整数数组 n u m s nums nums 和一个二维数组 q u e r i e s queries queries&#xff0c;其中 q u e r i e s [ i ] [ l i , r i ] queries[i] [l_i, r_i] queries[i][li​,ri​]。 对于每个查询 q u e r i e s [ i ] queries[i] quer…...

RK3588 ArmNN CPU/GPU ResNet50 FP32/FP16/INT8 推理测试

RK3588 ArmNN CPU/GPU ResNet50 FP32/FP16/INT8 推理测试 **背景与目标** 一.性能数据【INT8模型在CPU上推理的结果已经不对,暂未分析原因】二.操作步骤2.1 在x86-Linux上生成onnx模型,以及tflite量化模型(避免在RK3588上安装过多依赖)2.1.1 创建容器2.1.2 安装依赖2.1.3 下载推…...