基于SpringBoot+Vue3的在线报名系统

news2024/11/17 5:59:26

一、项目介绍

1.1 项目介绍

本项目为一个报名系统,实现了基本的报名流程,功能完善,前后端皆有个人独立开发,功能相对不是特别难,但该有的功能还是都已经实现。

1.2 技术架构

主要技术栈: SpringBoot2 + Vue3 + MySQL8.0

1.3 主要功能

角色设计: 管理员/普通用户(报名者)

首页

数据信息

        报名详情 / 报名表 / 黑名单 / 信息列表

权限设置

        角色管理 / 用户管理

系统设置

        修改密码

管理员默认拥有所有权限,而普通用户则只拥有 首页/ 数据信息(报名详情、报名表)/ 系统设置(修改密码)权限信息可以修改。

1.4 运行项目

前端:

 # 安装依赖
 npm install
 ​
 # 启动开发服务器
 npm run dev

高德地图密钥配置:在MapContrainer.vue中配置高德地图的密钥 ,如果没有请先去高德地图开发者平台注册

 window._AMapSecurityConfig = {
     securityJsCode: "你的安全密钥",
   };
   AMapLoader.load({
     key: "Web端开发者Key", // 申请好的Web端开发者Key,首次调用 load 时必填
     version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
     plugins: ["AMap.Geolocation"], // 只使用 Geolocation 插件
   })

启动,访问 http://localhost:5173/

后端:

要启动你的项目,其他开发者需要按照以下步骤操作:

  1. 配置环境: 确保安装了以下环境和工具:

    • JDK 8 或更高版本

    • Maven

    • MySQL 数据库

  2. 配置数据库

    • 创建一个新的 MySQL 数据库。

    • 在 `src/main/resources/application.yaml 文件中配置数据库连接信息:

  3. 安装依赖: 使用 Maven 安装项目依赖:

     mvn clean install
  4. 运行项目,打开浏览器,访问 http://localhost:8085。

通过以上步骤,其他开发者应该能够成功启动并运行你的项目。

二、数据库设计

此项目共包含6张表; apply 报名表、 blacklist 黑名单、 information 报名信息表、menu 权限菜单表、 role角色表、 user 用户表。

各表设计如下:

 -- 报名列表 
 -- auto-generated definition
 create table apply
 (
   id          int auto_increment
   primary key,
   type_id     int           not null,
   typename    varchar(32)   not null,
   is_delete   int default 0 not null,
   description varchar(128)  null,
   is_show     int default 0 not null,
   begin_time  datetime      not null,
   end_time    datetime      not null
 )
     comment '报名列表';
 ​
     -- 黑名单 
 -- auto-generated definition
 create table blacklist
 (
   id           int auto_increment
   primary key,
   user_id      int           not null,
   is_delete    int default 0 not null,
   name         varchar(24)   not null comment '用户名',
   grade        int           not null,
   professional varchar(32)   not null comment '专业',
   description  varchar(128)  null comment '描述',
   add_time     datetime      not null,
   school       varchar(64)   not null comment '学校'
 )
     comment '黑名单';
 ​
     -- 报名信息表 
 -- auto-generated definition
 create table information
 (
   id            int auto_increment
   primary key,
   user_id       int                        not null comment '用户id',
   name          varchar(32)                not null,
   apply_id      int                        not null,
   is_delete     int         default 0      not null,
   user_add_time datetime                   not null,
   school        varchar(32)                not null,
   professional  varchar(32) default '其他' not null comment '专业',
   grades        int                        not null comment '年级',
   phone         varchar(32)                not null,
   email         varchar(128)               not null,
   sex           varchar(24)                not null
 )
     comment '报名信息表';
 ​
     -- 权限列表 
 -- auto-generated definition
 create table menu
 (
   id   int auto_increment comment '主键id'
   primary key,
   name varchar(32)   not null comment '菜单名称',
   path varchar(64)   not null comment '路径',
   icon varchar(32)   not null comment '菜单的图标',
   pid  int default 0 not null
 )
     comment '权限列表';
 ​
     -- 用户角色列表 
 -- auto-generated definition
 create table role
 (
   id          int auto_increment comment '主键id'
   primary key,
   role_name   varchar(32)                         not null comment '角色名称',
   is_delete   int          default 0              not null comment '0 启用, 1 禁用',
   description varchar(128) default '暂无具体描述' not null comment '描述',
   rights      json                                null comment '角色所拥有的权限'
 )
     comment '用户角色列表';
 ​
 ​
 -- 用户列表 
 -- auto-generated definition
 create table user
 (
   id          int auto_increment comment '主键id'
   primary key,
   user_name   varchar(32)                            not null comment '用户名',
   password    varchar(32) default '123'              not null comment '密码',
   role_id     int                                    not null comment '角色ID',
   description varchar(64) default '暂无具体描述信息' not null comment '描述',
   is_delete   int         default 0                  not null comment '是否已经被删除,0 : 启用, 1:已经被删除'
 )
     comment '用户列表';

三、后端

3.1 项目资源一览:

3.2 Jwt的使用

配置Jwt的主要过程如下:

3.2.1 引入依赖/ 配置参数
 <!-- JWT -->
         <dependency>
             <groupId>io.jsonwebtoken</groupId>
             <artifactId>jjwt</artifactId>
             <version>0.9.1</version>
         </dependency>
         <dependency>
             <groupId>com.auth0</groupId>
             <artifactId>java-jwt</artifactId>
             <version>3.19.2</version>
         </dependency>
         <!--jdk大于8时需要添加-->
         <dependency>
             <groupId>javax.xml.bind</groupId>
             <artifactId>jaxb-api</artifactId>
         </dependency>

在application.yaml中配置:

 config:
   jwt:
     secret: 123456 # 密钥
     expire: 36000 # 过期时间
     header: token # 请求头名称
3.2.2 创建JwtConfig配置类
package com.registration.registration_system.config;
 ​
 import io.jsonwebtoken.Claims;
 import io.jsonwebtoken.Jwts;
 import io.jsonwebtoken.SignatureAlgorithm;
 import lombok.Data;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.stereotype.Component;
 ​
 import java.util.Date;
 ​
 @ConfigurationProperties(prefix = "config.jwt", ignoreUnknownFields = true)
 @Component
 @Data
 public class JwtConfig {
     private String secret;
     private long expire;
     private String header;
 ​
     // 生成token
     public String createToken(String subject) {
         // 当前时间与过期时间
         Date now = new Date();
         Date expireDate = new Date(now.getTime() + expire*1000);
         return Jwts.builder()
                 .setHeaderParam("typ", "JWT")
                 .setSubject(subject) // 设置主题
                 .setIssuedAt(now)  // 设置签发时间
                 .setExpiration(expireDate)  // 设置过期时间
                 .signWith(SignatureAlgorithm.HS512, secret)  // 设置签名
                 .compact();
     }
     // 解析token
     public Claims getTokenClaims(String token) {
         try {
             return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
         } catch (Exception e) {
             throw new RuntimeException(e);
         }
     }
 ​
     // 获取token中的用户名
     public String getUsernameFromToken(String token) {
         Claims claims = getTokenClaims(token);
         if (claims != null) {
             return claims.getSubject();
         }
         return null;
     }
 }
 
3.2.3 创建一个拦截器 TokenInterceptor,添加 JwtConfig配置类
 
 
package com.registration.registration_system.config;
 ​
 import lombok.AllArgsConstructor;
 import org.springframework.stereotype.Component;
 import org.springframework.util.StringUtils;
 import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
 ​
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 ​
 @Component
 @AllArgsConstructor
 public class TokenInterceptor extends HandlerInterceptorAdapter {
     private final JwtConfig jwtConfig;
 ​
     @Override
     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 获取请求头中的token
         String token = request.getHeader(jwtConfig.getHeader());
 ​
         // 如果token为空
         if(StringUtils.isEmpty(token)) {
             sendError(response, "token为空");
             return false;
         }
         // 解析token
         try {
             jwtConfig.getTokenClaims(token);
         } catch (Exception e) {
             sendError(response, "token过期或不正确,请重新登录");
             return false;
         }
         return true;
     }
     // 返回错误信息
     private void sendError(HttpServletResponse response, String message) {
         response.setStatus(401);
         response.setContentType("application/json;charset=UTF-8");
         response.setCharacterEncoding("UTF-8");
         try {
             response.getWriter().write(message);
         } catch (Exception e) {
             e.printStackTrace();
         }
     }
 }
3.2.4 添加自定义的拦截器到webConfig配置类中
 
package com.registration.registration_system.config;
 ​
 import lombok.AllArgsConstructor;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.web.servlet.config.annotation.CorsRegistry;
 import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 @Configuration
 @AllArgsConstructor
 public class WebConfig implements WebMvcConfigurer {
 ​
     private final TokenInterceptor tokenInterceptor;
 ​
     /**
      * 拦截器配置
      * @param registry
      */
     @Override
     public void addInterceptors(InterceptorRegistry registry) {
         registry.addInterceptor(tokenInterceptor)
                 .addPathPatterns("/**")
                 .excludePathPatterns("/adminapi/user/login/**");
     }
 ​
     /**
      * 跨域配置
      * @param registry
      */
     @Override
     public void addCorsMappings(CorsRegistry registry) {
         WebMvcConfigurer.super.addCorsMappings(registry);
     }
 }
 

到此,就已经配置好了jwt,使用示例如下,我们希望在调用登录接口的时候生成token并返回,主要代码可以在serviceImpl中实现:

 
/**
 * 登录
 * @param user
 * @return
 */
 @Transactional
 @Override
 public UserVo login(User user) {
   User new_user = userMapper.selectUser(user);
   if (new_user == null) {
     return null;
   } else {
     // 创建vo
     UserVo vo = new UserVo();
     BeanUtils.copyProperties(new_user, vo);
     // 生成token
     String token = jwtConfig.createToken(new_user.getUserName());
     vo.setToken(token);
     // 查询role
     Role role = new Role();
     role.setId(new_user.getRoleID());
     List<Role> roleList = roleMapper.selectRoleList(role);
     // 设置role为roleList的第一个
     vo.setRole(roleList.get(0));
     return vo;
   }
 }
3.3 PageHelper 分页插件
3.3.1 引入依赖
<!--分页插件-->
         <dependency>
             <groupId>com.github.pagehelper</groupId>
             <artifactId>pagehelper-spring-boot-starter</artifactId>
             <version>1.4.6</version>
         </dependency>
         <dependency>
             <groupId>com.github.jsqlparser</groupId>
             <artifactId>jsqlparser</artifactId>
             <version>4.2</version>
         </dependency>
3.3.2 使用
/**
      * 获取报名列表
      * @return
      */
     @Override
     public PageInfo<Apply> getApplyList(ApplyDto applyDto) {
         PageHelper.startPage(applyDto.getPageNum(), applyDto.getPageSize());
         Apply apply = new Apply();
         BeanUtils.copyProperties(applyDto, apply);
         List<Apply> applyList = applyMapper.selectApplyList(apply);
       return new PageInfo<>(applyList);
     }
 ​

分页插件的使用实际上非常简单,

首先,从前端接收到pageNum和PageSize之后,我们在serviceImpl层调用mapper接口之前,调用PageHelper.startPage来设置查询的数量和当前页。

然后我们正常进去查询,代码中所示是因为要有符合mapper接口的参数传入所以重新new了一个apply。

最后,返回一个 PageInfo<>类型的对象。

3.4 实现数据表导出成excel格式
/**
      * 导出信息
      * @param informationDto
      * @param response
      * @throws IOException
      */
     @Override
     public void exportInformation(InformationDto informationDto, HttpServletResponse response) throws IOException {
         // 创建一个 InformationVo 对象,并将 informationDto 的属性复制到该对象中
         InformationVo vo = new InformationVo();
         BeanUtils.copyProperties(informationDto, vo);
 ​
         // 创建一个空的列表,用于存储导出的数据
         List<Map<String, Object>> list = CollUtil.newArrayList();
         // 从数据库中查询信息列表
         List<InformationVo> infoList = informationMapper.selectInfoList(vo);
 ​
         // 遍历查询到的信息列表,将每条信息转换为 Map 并添加到 list 中
         for (InformationVo info : infoList) {
             Map<String, Object> row1 = new LinkedHashMap<>();
             row1.put("用户编号", info.getUserId());
             row1.put("姓名", info.getName());
             row1.put("性别", info.getSex());
             row1.put("参报项目", info.getTypeName());
             row1.put("报名时间", info.getUserAddTime());
             row1.put("学校", info.getSchool());
             row1.put("年级", info.getGrades());
             row1.put("专业", info.getProfessional());
             row1.put("手机号码", info.getPhone());
             row1.put("邮箱", info.getEmail());
 ​
             // 将每条信息的 Map 添加到 list 中
             list.add(row1);
         }
 ​
         // 创建一个 ExcelWriter 对象,用于写入 Excel 文件
         ExcelWriter writer = ExcelUtil.getWriter(true);
         // 一次性写出内容,强制输出标题
         writer.write(list, true);
 ​
         // 设置响应头,指定内容类型和文件名
         response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
         String fileName = URLEncoder.encode("下载信息", "UTF-8");
         response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
 ​
         // 获取响应的输出流
         ServletOutputStream out = response.getOutputStream();
         // 将 ExcelWriter 中的数据刷新到输出流中
         writer.flush(out, true);
         // 关闭 ExcelWriter,释放内存
         writer.close();
         // 关闭输出流
         IoUtil.close(System.out);
     }

Controller层接收一个额外参数response,然后我们在Service实现类中,先查询需要导入的数据,然后生成表头,最后写入Excel文件。

四、前端

本节主要记录在进行前端开发时所用到的一些插件

4.1 js-file-download

js-file-download 是一个用于在浏览器中触发文件下载的 JavaScript 库。它可以方便地将数据(如文本、JSON、二进制数据等)下载为文件,而无需服务器端的支持。这个库非常适合用于前端应用程序中需要生成和下载文件的场景。

4.1.1安装
 npm install js-file-download
 # 或者
 yarn add js-file-download
4.2.2 使用
 <template>
   <div>
     <el-button type="success" @click="handleExport">
             导出
             <el-icon><Download /></el-icon>
     </el-button>
   </div>
 </template>
 ​
 <script setup>
 import fileDownload from 'js-file-download';
 ​
 const handleExport = async () => {
   try {
     const res = await axios.get(
       `/adminapi/user/export?userName=${searchValue.value.userName}&roleName=${searchValue.value.roleName}`,
       {
         responseType: "blob",
       }
     );
     // console.log(res);
     fileDownload(
       res.data,
       "注册用户列表" + new Date().toLocaleString() + ".xlsx"
     );
     ElMessage.success("导出成功");
   } catch (error) {
     ElMessage.error("导出失败");
   }
 };
 </script>
 ​
 <style scoped>
 /* 添加你的样式 */
 </style>

这段代码使用 axios 发送 GET 请求以获取用户列表的 Excel 文件,并使用 js-file-download 库在浏览器中触发文件下载,同时显示导出成功或失败的消息。

4.2 tsparticles

tsparticles 是一个用于创建和管理粒子动画效果的 JavaScript 库。它可以在网页上生成各种粒子效果,如雪花、星空、气泡等,适用于背景动画、交互效果等场景。这个库非常灵活,支持多种配置和自定义效果。

4.2.1 安装
 npm install tsparticles
 # 或者
 yarn add tsparticles
4.2.2 使用
 <template>
   <vue-particles
     id="tsparticles"
     @particles-loaded="particlesLoaded"
     :options="tsOption"
   />
 </template>
 ​
 <script setup>
 import tsOption from "@/utils/tspartice.js";
 ​
 // 粒子效果
 const particlesLoaded = async (container) => {
   console.log("Particles container loaded", container);
 };
 </script>
 ​
 <style scoped>
 ​
 </style>

其中,tspartice.js文件 (由于内容过多显示部分):

 const option = {
   autoPlay: true,
   background: {
     color: {
       value: "#043564",
     },
     image: "url('./bg.png')",
     position: "0 50%",
     repeat: "no-repeat",
     size: "100%",
     opacity: 1,
   },
   backgroundMask: {
     composite: "destination-out",
     cover: {
       color: {
         value: "#fff",
       },
       opacity: 1,
     },
     enable: false,
   },
   clear: true,
   defaultThemes: {},
   delay: 0,
   fullScreen: {
     enable: true,
     zIndex: 0,
   },
   ...
 };
 ​
 export default option;
 ​
4.3 dayjs

dayjs 是一个轻量级的 JavaScript 日期库,具有与 Moment.js 类似的 API,但体积更小,性能更高。它用于解析、验证、操作和显示日期和时间。

  1. 解析日期:支持多种日期格式的解析。

  2. 格式化日期:可以将日期格式化为各种字符串格式。

  3. 操作日期:支持日期的加减操作。

  4. 本地化:支持多种语言的本地化。

  5. 插件系统:通过插件扩展功能,如相对时间、UTC、时区等。

4.3.1 安装
 npm install dayjs
 # 或者
 yarn add dayjs
4.3.2 使用
import dayjs from 'dayjs';
 ​
 // 解析日期
 const now = dayjs();
 console.log(now.format()); // 当前日期和时间
 ​
 // 格式化日期
 const formattedDate = now.format('YYYY-MM-DD');
 console.log(formattedDate); // 例如:2023-10-01
 ​
 // 操作日期
 const nextWeek = now.add(7, 'day');
 console.log(nextWeek.format('YYYY-MM-DD')); // 例如:2023-10-08
 ​
 // 本地化
 import 'dayjs/locale/zh-cn';
 dayjs.locale('zh-cn');
 console.log(now.format('MMMM D, YYYY')); // 例如:十月 1, 2023
4.4 其他插件
4.4.1 ECharts

主要功能: ECharts 是一个基于 JavaScript 的图表库,支持多种图表类型(如折线图、柱状图、饼图等),并提供丰富的交互功能。适合用于可视化数据展示。

安装方法:

npm install echarts --save
4.4.2 Element Plus 和 @element-plus/icons-vue

主要功能:

  • Element Plus: 一个基于 Vue 3 的 UI 组件库,提供了一系列高质量的组件,帮助开发者快速构建用户界面。

  • @element-plus/icons-vue: 提供 Element Plus 组件库的图标集,方便在项目中使用。

安装方法:

 npm install element-plus --save
 npm install @element-plus/icons-vue --save
4.4.3 Vue Router

主要功能: Vue Router 是 Vue.js 官方的路由管理器,允许开发者创建单页应用程序(SPA)时实现页面导航。支持动态路由匹配、嵌套路由等功能。

安装方法:

 npm install vue-router@4 --save
4.4.4 Pinia 和 pinia-plugin-persistedstate

主要功能:

  • Pinia: Vue 3 的状态管理库,提供了简单易用的 API 和类型支持,成为 Vuex 的替代品。

  • pinia-plugin-persistedstate: Pinia 的一个插件,用于将状态持久化存储到本地存储或其他存储方案,以便在页面刷新后保持状态。

安装方法:

 npm install pinia --save
 npm install pinia-plugin-persistedstate --save
4.4.5 @amap/amap-jsapi-loader

主要功能: AMap JavaScript API Loader 是一个加载高德地图 JavaScript API 的工具,简化了 API 的引入和使用,使得开发者能够方便地在 Vue 项目中集成高德地图服务。

安装方法:

 npm install @amap/amap-jsapi-loader --save
4.5 页面展示

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【LLM学习之路】9月25日26日27日 第十二、十三、十四天 Transformer Encoder

【LLM学习之路】9月25日26日27日 第十二、十三、十四天 Transformer Encoder Encoder 负责将输入的词语序列转换为词向量序列&#xff0c;Decoder 则基于 Encoder 的隐状态来迭代地生成词语序列作为输出&#xff0c;每次生成一个词语。 王木头 词向量&#xff0c;使用高维向…

教师工作量|基于springBoot的教师工作量管理系统设计与实现(附项目源码+论文+数据库)

私信或留言即免费送开题报告和任务书&#xff08;可指定任意题目&#xff09; 目录 一、摘要 二、相关技术 三、系统设计 四、数据库设计 五、核心代码 六、论文参考 七、源码获取 一、摘要 传统信息的管理大部分依赖于管理人员的手工登记与管理&#xff…

论文笔记(四十七)Diffusion Policy: Visuomotor Policy

Diffusion Policy: Visuomotor Policy 文章概括摘要1. 介绍2. 扩散策略的公式化2.1 去噪扩散概率模型2.2 DDPM 训练2.3 用于视觉运动策略学习的扩散模型 3 关键设计决策3.1 网络架构选项3.2 视觉编码器3.3 噪声计划3.4 加速实时控制的推理 4. 扩散策略的四个引人入胜的特性4.1 …

Meta号称替代程序员的LlamaCoder效果被CodeFlying秒杀,来看实测!

在讲LlamaCoder之前咱先浅聊一下Meta 这两天Meta凭借着Connect 2024大会可谓是风头正盛&#xff0c;刚刚发布的全新开源多模态大模型Llama3.2&#xff0c;热度是一路赶超咱的小草莓啊。 作为一款开源大模型能够和闭源的4o-mini、Claude3 Haiku打的有来有回&#xff0c; 甚至L…

protobuf编码方式

protobuf编码方式 一个简单的例子 message Test1 {optional int32 a 1; }上述的proto文件&#xff0c;设置a 150&#xff0c;那么将其序列化后&#xff0c;得到的数据就是08 96 01&#xff0c;然后你使用protoscope工具去解析这些数据&#xff0c;就得到1 : 150&#xff0c…

labview更换操作系统后打开原VI闪退

labview更换操作系统后打开原VI闪退 问题描述&#xff1a; Windows11由家庭版更换为专业版后&#xff0c;重新安装labview2021&#xff0c;打开原来的项目&#xff0c;项目管理器可以正常打开&#xff0c;但是打开VI却闪退&#xff0c;并报错如下 出现这种原因主要是labview在…

Kubernetes深入详解(一)

目录 第一部分 K8s概念和架构 1、k8s概述和特性 2、K8s架构组件 3、k8s核心概念 第二部分 从零搭建k8s集群 1、搭建k8s环境平台规划 2、服务器硬件配置要求 3、搭建k8s集群部署方式 (1) 基于客户端工具kubeadm 1、安装Docker 2、添加阿里云YUM软件源 3、安 装kubea…

16.第二阶段x86游戏实战2-发包函数和怎么去找改写过的发包函数

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 本人写的内容纯属胡编乱造&#xff0c;全都是合成造假&#xff0c;仅仅只是为了娱乐&#xff0c;请不要…

Stable Diffusion 优秀博客转载

初版论文地址&#xff1a;https://arxiv.org/pdf/2112.10752 主要流程图&#xff1a; Latent Diffusion Models&#xff08;LDMs&#xff09; DDPM是"Denoising Diffusion Probabilistic Models"的缩写&#xff0c; 去噪扩散概率模型 博客&#xff1a; https://ja…

【CSS in Depth 2 精译_041】6.4 CSS 中的堆叠上下文与 z-index(上)

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第一章 层叠、优先级与继承&#xff08;已完结&#xff09;第二章 相对单位&#xff08;已完结&#xff09;第三章 文档流与盒模型&#xff08;已完结&#xff09;第四章 Flexbox 布局&#xff08;已…

AT89C51 利用SBIT寻址,并且在内存中实现伪动态密码的混淆

前置发现 && 分析 char bdata DB[2]; //char sbit x bdata DB[0]^7; //取内存地址数组[0]地址的的七位 这样我们可以对数组DB中索引0的位置进行修改… 例如,将密码A映射到真实密码C,这样做的好处是你的程序被逆向分析的时候,攻击者无法真正知道密码到底是什么…因为…

C语言-线程

一,线程的概念 1,线程的定义 在 C 语言中&#xff0c;线程是程序执行的最小单位&#xff0c;它是进程中的一个实体&#xff0c;是被系统独立调度和分派的基本单位。 2、线程的特点 轻型实体&#xff1a;线程是一个轻型实体&#xff0c;它只拥有必不可少的资源&#xff0c;如程…

学生党有福了!分享5个免费的AI论文生成工具

学生党在学术写作方面常常面临时间紧迫和写作能力不足的问题。幸运的是&#xff0c;随着人工智能技术的发展&#xff0c;市面上出现了许多免费的AI论文生成工具&#xff0c;极大地提高了写作效率和质量。今天&#xff0c;我将向大家推荐五款免费的AI论文生成工具&#xff0c;并…

再也不用担心内容重复!在线伪原创工具,让创作更自由!

大家好&#xff0c;今天我们将讨论一个对网络写作非常有益的辅助工具——在线内容转换工具。不论您是需要更新您的博客&#xff0c;还是希望在社交平台上保持活跃&#xff0c;我们都频繁面临着迅速生成新内容的挑战。利用一个有效的工具来改写现有内容&#xff0c;可以极大地提…

一次实践:给自己的手机摄像头进行相机标定

文章目录 1. 问题引入2. 准备工作2.1 标定场2.2 相机拍摄 3. 基本原理3.1 成像原理3.2 畸变校正 4. 标定解算4.1 代码实现4.2 详细解析4.2.1 解算实现4.2.2 提取点位 4.3 解算结果 5. 问题补充 1. 问题引入 不得不说&#xff0c;现在的计算机视觉技术已经发展到足够成熟的阶段…

Python画笔案例-067 绘制配乐七角星

1、绘制橙子 通过 python 的turtle 库绘制 配乐七角星,如下图: 2、实现代码 绘制 配乐七角星 ,以下为实现代码: """配乐七角星.py本程序需要coloradd模块支持,安装方法:pip install coloradd""" import turtle from coloradd import color…

制造企业如何提升项目管理效率?惠科股份选择奥博思PowerProject项目管理系统

全球知名的显示方案综合服务商 - 惠科股份有限公司与北京奥博思达成合作&#xff0c;基于奥博思 PowerProject 搭建企业级项目管理平台。满足惠科多产品多业务领域的项目全周期管理。助力企业在技术研发、产品创新等方面继续取得行业领先优势。 同时&#xff0c;PowerProject …

如何进行u盘拷贝文件管控?5个方法一文详情告诉你!

小李&#xff1a;老王&#xff0c;最近我们部门经常提到数据安全的问题&#xff0c;特别是U盘拷贝文件带来的风险。 你有什么好办法可以管控一下吗&#xff1f; 老王&#xff1a;小李啊&#xff0c;你问对人了。 U盘拷贝文件管控确实是个头疼的问题&#xff0c;但我们可以从…

C++入门day5-面向对象编程(终)

C入门day4-面向对象编程&#xff08;下&#xff09;-CSDN博客 本节是我们面向对象内容的最终篇章&#xff0c;不是说我们的C就学到这里。如果有一些面向对象的基础知识没有讲到&#xff0c;后面会发布在知识点补充专栏&#xff0c;全都是干货满满的。 https://blog.csdn.net/u…

【中级通信工程师】终端与业务(九):市场细分与选择

【零基础3天通关中级通信工程师】 终端与业务(九)&#xff1a;市场细分与选择 本文是中级通信工程师考试《终端与业务》科目第九章《市场细分与选择》的复习资料和真题汇总。本章的核心内容涵盖了市场细分的概念与方法、目标市场选择策略以及市场定位的原则和步骤。通过本节的…