探花交友_第10章_搭建后台系统(新版)

news2024/11/19 2:26:58

探花交友_第10章_搭建后台系统(新版)

文章目录

  • 探花交友_第10章_搭建后台系统(新版)
      • 1.1 概述
      • 1.2 API网关
        • 1.2.1 搭建网关
          • 依赖
          • 引导类
          • 跨域问题配置类
          • 配置文件
          • 测试
        • 1.2.2 配置鉴权管理器
      • 1.3 Nacos配置中心
        • 1.3.1 添加依赖
        • 1.3.2 添加bootstrap.yml配置
        • 1.3.3 nacos添加配置
    • 2、后台系统
      • 2.1 概述
      • 2.2 环境前端搭建
        • 2.2.1 导入数据库
        • 2.2.2 导入静态页面
          • nginx安装
          • 测试
      • 2.3 搭建后端环境
        • 2.3.1 实体类Admin
        • 2.3.2 导入项目
        • 2.3.3 创建配置文件
      • 2.4 管理员登录
        • 2.4.1 生成验证码
          • 接口文档
          • SystemController
        • 2.4.2 用户登录
          • 接口文档
          • SystemController
          • SystemService
        • 2.4.3 获取用户资料
          • 接口文档
          • AdminVO
          • SystemController
          • SystemService
    • 3、用户管理
      • 3.1 需求分析
      • 3.2 查询用户列表
        • 后台系统
          • ManageController
          • ManagerService
        • 服务提供者
          • UserInfoApi
          • UserInfoImpl
      • 3.3 查看用户详情
        • tanhu-admin
          • ManageController
          • ManagerService
      • 3.4 查看视频列表
        • tanhua-admin
          • ManageController
          • ManagerService
        • tanhua-dubbo-interface
        • tanhua-dubbo-mongo
      • 3.5 查看动态列表
        • tanhua-admin
          • ManageController
          • ManagerService
        • tanhua-dubbo-interface
        • tanhua-dubbo-mongo

1.1 概述

API网关有很多实现方式,我们通过SpringCloud Gateway实现

使用Nacos作为配置中心

在这里插入图片描述

1.2 API网关

1.2.1 搭建网关

需求:创建新的网关模块tanhua-gateway,并配置路由

依赖
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>

    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>

    <!-- 监控检查-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <!-- nacos配置中心依赖支持
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>
    -->
    <dependency>
        <groupId>com.itheima</groupId>
        <artifactId>tanhua-commons</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
</dependencies>
引导类

tanhua-gateway模块配置引导类

@SpringBootApplication
public class GatewayApplication {

    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}
跨域问题配置类
package com.itheima.gateway.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.util.pattern.PathPatternParser;

/**
 * 跨域支持
 */
@Configuration
public class CorsConfig {

    @Bean
    public CorsWebFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedMethod("*");
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        UrlBasedCorsConfigurationSource source =
                new UrlBasedCorsConfigurationSource(new PathPatternParser());
        source.registerCorsConfiguration("/**", config);
        return new CorsWebFilter(source);
    }
}
配置文件
server:
  port: 8888
spring:
  application:
    name: tanhua-gateway
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.136.160:8848
    gateway:
      globalcors:
        add-to-simple-url-handler-mapping: true
        corsConfigurations:
          '[/**]':
            allowedHeaders: "*"
            allowedOrigins: "*"
            allowedMethods:
              - GET
              - POST
              - DELETE
              - PUT
              - OPTION
      routes:
        # 手机端访问
        - id: tanhua-app-server
          uri: lb://tanhua-app-server
          predicates:
            - Path=/app/**
          filters:
            - StripPrefix= 1
        # 管理后台
        - id: tanhua-admin
          uri: lb://tanhua-admin
          predicates:
            - Path=/admin/**
          filters:
            - StripPrefix= 1
#自定义配置,定义不需要校验token的连接
gateway:
  excludedUrls: /user/login,/user/loginVerification,/system/users/verification,/system/users/login
测试

由于加入了网关,所有的请求统一发送到网关,路由到具体的服务。测试时注意修改请求地址

tanhua-app-server访问地址 ip:8888/app/ (IP以自己模拟器为准)

在这里插入图片描述

1.2.2 配置鉴权管理器

在网关内部可以通过过滤器完成统一鉴权,限流,日志记录等操作。

在这里插入图片描述

tanhua-gateway模块配置鉴权过滤器

@Component
public class AuthFilter implements GlobalFilter, Ordered {

    @Value("${gateway.excludedUrls}")
    private List<String> excludedUrls; //配置不校验的连接

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //获取当前请求连接
        String url = exchange.getRequest().getURI().getPath();
        System.out.println( "url:"+ url);
        //放行不需要校验的接口
        if(excludedUrls.contains(url)){
            return chain.filter(exchange);
        }
        //获取请求头中的token
        String token = exchange.getRequest().getHeaders().getFirst("Authorization");
        //后台系统页面发送的token以"Bearer "开头,需要处理
        if(!StringUtils.isEmpty(token)){
            token = token.replace("Bearer ", "");
        }
        ServerHttpResponse response = exchange.getResponse();

        //使用工具类,判断token是否有效
        boolean verifyToken = JwtUtils.verifyToken(token);
        //如果token失效,返回状态码401,拦截
        if(!verifyToken) {
            Map<String, Object> responseData = new HashMap<>();
            responseData.put("errCode", 401);
            responseData.put("errMessage", "用户未登录");
            return responseError(response,responseData);
        }
        return chain.filter(exchange);
    }

    //响应错误数据
    private Mono<Void> responseError(ServerHttpResponse response,Map<String, Object> responseData){
        // 将信息转换为 JSON
        ObjectMapper objectMapper = new ObjectMapper();
        byte[] data = new byte[0];
        try {
            data = objectMapper.writeValueAsBytes(responseData);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        // 输出错误信息到页面
        DataBuffer buffer = response.bufferFactory().wrap(data);
        response.setStatusCode(HttpStatus.UNAUTHORIZED);
        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        return response.writeWith(Mono.just(buffer));
    }

    /**
     * 设置过滤器的执行顺序
     */
    @Override
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE;
    }
}

1.3 Nacos配置中心

Nacos提供了注册中心和配置管理的能力,使用Nacos可以快速实现服务发现、服务配置管理等需求。

这里以网关工程(tanhua-gateway)为例

在这里插入图片描述

1.3.1 添加依赖

tanhua-gateway模块中添加配置中心依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

1.3.2 添加bootstrap.yml配置

tanhua-gateway模块中添加引导文件bootstrap.yml,并设置

server:
  port: 8888
spring:
  profiles:
    active: prod
  application:
    name: tanhua-gateway
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.136.160:8848
      config:
        server-addr: 192.168.136.160:8848
        file-extension: yml

1.3.3 nacos添加配置

在nacos中添加网关配置

在这里插入图片描述

添加配置内容

在这里插入图片描述

配置如下内容

server:
  port: 8888
spring:
  cloud:
    gateway:
      globalcors:
        add-to-simple-url-handler-mapping: true
        corsConfigurations:
          '[/**]':
            allowedHeaders: "*"
            allowedOrigins: "*"
            allowedMethods:
              - GET
              - POST
              - DELETE
              - PUT
              - OPTION
      routes:
        # 用户微服务
        - id: tanhua-app-server
          uri: lb://tanhua-app-server
          predicates:
            - Path=/app/**
          filters:
            - StripPrefix= 1
        # 文章微服务
        - id: tanhua-admin
          uri: lb://tanhua-admin
          predicates:
            - Path=/admin/**
          filters:
            - StripPrefix= 1
gateway:
  excludedUrls: /user/login,/user/loginVerification,/system/users/verification,/system/users/login

2、后台系统

2.1 概述

探花交友APP建立的后台管理系统,目的是完成探花交友项目的业务闭环,主要功能包括:用户管理、动态管理、审核管理以及系统管理。

在这里插入图片描述

课程中实现的功能有:登录、首页、用户管理、动态审核。

2.2 环境前端搭建

2.2.1 导入数据库

将资料中的tanhua-admin.sql引入到mysql数据库中

在这里插入图片描述

2.2.2 导入静态页面

后台系统也是采用前后端分离的方式,前端采用Vue.js实现,关于前端系统我们不进行实现,拿来直接使用。

在这里插入图片描述

nginx安装

将资料中提供的nginx解压到合适的位置

在这里插入图片描述

其中html目录中为,vue编译后的所有页面。

修改Nginx的/conf/nginx.conf配置文件:

    server {
        listen       8088;  #请求端口
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;
		

		location / {
            root   html;
            index  index.html index.htm;
        }
		
		location  /management {
			proxy_pass http://127.0.0.1:8888/admin;  #转发java后台网关地址
		}
		#....略
	}
  • 访问vue页面的路径:localhost:8088
  • 其中内部调用java服务器网关的路径 : http://127.0.0.1:8888/admin
测试

双击nginx.exe,待启动完成后访问:http://127.0.0.1:8088即可访问后台项目

2.3 搭建后端环境

后端工程模块是准备好的,依赖两个实体类,这里先准备好。

2.3.1 实体类Admin

admin:是后台中超级管理员对象

package com.tanhua.model.admin;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

//后台系统的管理员对象
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Admin implements Serializable {
    /**
     * id
     */
    private Long id;
    /**
     * 用户名
     */
    private String username;
    /**
     * 密码
     */
    private String password;
    /**
     * 头像
     */
    private String avatar;
}

2.3.2 导入项目

将今日资料中的tanhua-admin模块导入到探花项目中,完成开发。

在这里插入图片描述

2.3.3 创建配置文件

创建application.yml配置文件

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/tanhua-admin?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&useSSL=false
    username: root
    password: root
  rabbitmq:
    host: 192.168.136.160
    port: 5672
    username: guest
    password: guest    
  redis:
    host: 192.168.136.160
    port: 6379
  cloud:  #nacos配置
    nacos:
      discovery:
        server-addr: 192.168.136.160:8848
dubbo:    #dubbo配置
  registry:
    address: spring-cloud://localhost
  consumer:
    check: false
    retries: 0
  protocols:
    dubbo:
      port: -1

#配置短信平台信息
tanhua:  #手机验证码,咱们自己注册(不要白嫖)
  sms:
    signName: 物流云商
    templateCode: SMS_106590012
    accessKey: LTAI4GKgob9vZ53k2SZdyAC7
    secret: LHLBvXmILRoyw0niRSBuXBZewQ30la
  oss:
    accessKey: LTAI4GKgob9vZ53k2SZdyAC7
    secret: LHLBvXmILRoyw0niRSBuXBZewQ30la
    endpoint: oss-cn-beijing.aliyuncs.com
    bucketName: tanhua143
    url: https://tanhua143.oss-cn-beijing.aliyuncs.com
  aip:
    appId: 22837663
    apiKey: nA43galrxfUZTGtYRVK8F8tb
    secretKey: MQp567q4nGnIKfniURa2XAw8bT1SlPE3
  huanxin:
    appkey: 1110201018107234#tanhua
    clientId: YXA6nxJJ_pdEQ_eYUlqcRicS4w
    clientSecret: YXA6GMUxVEZhAvxlMn4OvHSXbWuEUTE
#mybaits-plus
mybatis-plus:
  global-config:
    db-config:
      table-prefix: tb_    #数据库表前缀
      id-type: auto        #数据库表主键的策略

2.4 管理员登录

后台系统的登录模块独立于APP端的登录。

2.4.1 生成验证码

验证码:页面端发送请求到服务端。服务端生成一个验证码的图片,已流的形式返回

接口文档

接口地址:http://192.168.136.160:3000/project/25/interface/api/322

在这里插入图片描述

  • 手机端获取验证码可以通过手机号码保证唯一性。

  • 页面端验证码自动生成UUID保证唯一性

SystemController

tanhua-admin模块中的SystemController中添加方法。

/**
 * 生成图片验证码
 */
@GetMapping("/verification")
public void verification(String uuid, HttpServletResponse response) throws IOException {
    //1、通过工具类生成验证码对象(图片数据和验证码信息)
    LineCaptcha captcha = CaptchaUtil.createLineCaptcha(299, 97);
    String code = captcha.getCode(); 
    //2、调用service,将验证码存入到redis
    redisTemplate.opsForValue().set(Constants.CAP_CODE+uuid,code);
    //3、通过输出流输出验证码
    captcha.write(response.getOutputStream());
}

2.4.2 用户登录

接口文档

接口地址:http://192.168.136.160:3000/project/25/interface/api/313

在这里插入图片描述

SystemController
/**
 * 用户登录
 */
@PostMapping("/login")
public ResponseEntity login(@RequestBody Map map) {
    Map retMap = adminService.login(map);
    return ResponseEntity.ok(retMap);
}
SystemService
//用户登录
public ResponseEntity login(Map map) {
    //1、获取请求的参数(username,password,verificationCode(验证码),uuid)
    String username = (String) map.get("username");
    String password = (String) map.get("password");
    String verificationCode = (String) map.get("verificationCode");
    String uuid = (String) map.get("uuid");
    //2、判断用户名或者密码是否为空
    if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
        //用户名或者密码为空
        //throw new BusinessException("用户名或者密码为空");
        Map map1 = new HashMap();
        map.put("message","用户名或者密码为空");
        return ResponseEntity.status(500).body(map1);
    }
    //3、判断验证码是否正确
    if (StringUtils.isEmpty(username)) {
        //验证码为空
        throw new BusinessException("验证码为空");
    }
    //从redis中获取验证码
    String key = Constants.CAP_CODE+uuid;
    String code = redisTemplate.opsForValue().get(key);
    if (StringUtils.isEmpty(code) || !code.equals(verificationCode)) {
        //验证码错误
        throw new BusinessException("验证码错误");
    }
    redisTemplate.delete(key);
    //4、根据用户名查询用户
    QueryWrapper<Admin> qw = new QueryWrapper<>();
    qw.eq("username", username);
    Admin admin = adminMapper.selectOne(qw);
    //5、判断用户是否存在,密码是否一致
    password = SecureUtil.md5(password); //md5加密
    if(admin == null || !admin.getPassword().equals(password)) {
        //用户名错误或者密码不一致
        throw new BusinessException("用户名或者密码");
    }
    //6、通过JWT生成token
    Map<String, Object> claims = new HashMap<String, Object>();
    claims.put("username", username);
    claims.put("id", admin.getId());
    String token = JwtUtils.getToken(claims);
    //8、构造返回值
    Map res = new HashMap();
    res.put("token", token);
    return ResponseEntity.ok(res);
}

2.4.3 获取用户资料

接口文档

文档地址:http://192.168.136.160:3000/project/25/interface/api/295

在这里插入图片描述

AdminVO
@Data
@NoArgsConstructor
@AllArgsConstructor
public class AdminVo {
    /**
     * id
     */
    private String id;
    /**
     * 用户名
     */
    private String username;

    /**
     * 头像
     */
    private String avatar;

    public static AdminVo init(Admin admin) {
        AdminVo vo = new AdminVo();
        vo.setAvatar(admin.getAvatar());
        vo.setUsername(admin.getUsername());
        vo.setId(admin.getId().toString());
        return vo;
    }

}
SystemController
/**
 * 获取用户的信息
 */
@PostMapping("/profile")
public ResponseEntity profile() {
    AdminVo vo = adminService.profile();
    return ResponseEntity.ok(vo);
}
SystemService
//获取当前用户的用户资料
public AdminVo profile() {
    Long id = AdminHolder.getId();
    Admin admin = adminMapper.selectById(id);
    return AdminVo.init(admin);
}

3、用户管理

3.1 需求分析

用户管理:对探花交友客户端注册用户的管理(查询业务数据),使用Dubbo的形式调用tanhua-dubbo-service获取响应的数据结果

3.2 查询用户列表

后台系统

tanhu-admin模块配置ManageControllerManagerService

ManageController
@GetMapping("/users")
public ResponseEntity users(@RequestParam(defaultValue = "1") Integer page,
                            @RequestParam(defaultValue = "10") Integer pagesize) {
   PageResult result = managerService.findAllUsers(page,pagesize);
   return ResponseEntity.ok(result);
}
ManagerService
public ResponseEntity findAllUsers(Integer page, Integer pagesize) {
    //1、调用API分页查询数据列表   Ipage<UserInfo>
    IPage<UserInfo> iPage = userInfoApi.findAll(page,pagesize);
    //2、需要将Ipage转化为PageResult
    PageResult result = new PageResult(page, pagesize, iPage.getTotal(), iPage.getRecords());
    //3、构造返回值
    return ResponseEntity.ok(result);
}

服务提供者

tanhua-dubbo-interface模块的UserInfoApi接口定义查询所有用户信息方法

tanhua-dubbo-db模块UserInfoImpl实现类中添加查询方法

UserInfoApi
/**
 * 分页查询所有用户信息
 *
 * @param page
 * @param pagesize
 * @return
 */
IPage findAll(Integer page, Integer pagesize);
UserInfoImpl

UserInfoApiImpl中实现查询所有用户信息方法

@Override
public IPage<UserInfo> findAll(Integer page, Integer pagesize) {
    return userInfoMapper.selectPage(new Page<UserInfo>(page,pagesize),null);
}

3.3 查看用户详情

tanhu-admin

ManageController
/**
 * 根据id查询用户详情
 *
 * @param userId
 * @return
 */
@GetMapping("/users/{userId}")
public ResponseEntity findUserById(@PathVariable("userId") Long userId) {
    UserInfo userInfo = managerService.findUserById(userId);
    return ResponseEntity.ok(userInfo);
}
ManagerService
/**
 * 根据用户ID查询用户详情
 *
 * @param userId
 * @return
 */
public UserInfo findUserById(Long userId) {
    return userInfoApi.findById(userId);
}

3.4 查看视频列表

tanhua-admin

tanhua-admin模块ManageControllerManagerService添加方法

ManageController
    /**
     * 查询指定用户发布的所有视频列表
     */
    @GetMapping("/videos")
    public ResponseEntity videos(@RequestParam(defaultValue = "1") Integer page,
                                 @RequestParam(defaultValue = "10") Integer pagesize,
                                 Long uid ) {
        PageResult result = managerService.findAllVideos(page,pagesize,uid);
        return ResponseEntity.ok(result);
    }
ManagerService
//查询指定用户发布的所有视频列表
public PageResult findAllVideos(Integer page, Integer pagesize, Long uid) {
    return videoApi.findByUserId(page, pagesize, uid);
}

tanhua-dubbo-interface

tanhua-dubbo-interface中的VideoApi中定义查询指定用户发布的视频列表方法

/**
 * 查询指定用户发布的视频列表
 *
 * @param page
 * @param pagesize
 * @param uid
 * @return
 */
PageResult findByUserId(Integer page, Integer pagesize, Long uid);

tanhua-dubbo-mongo

tanhua-dubbo-mongo中的VideoApiImpl中实现查询指定用户发布的视频列表方法

@Override
public PageResult findByUserId(Integer page, Integer pagesize, Long userId) {
    Query query = Query.query(Criteria.where("userId").in(userId));
    long count = mongoTemplate.count(query, Video.class);
    query.limit(pagesize).skip((page -1) * pagesize)
        .with(Sort.by(Sort.Order.desc("created")));
    List<Video> list = mongoTemplate.find(query, Video.class);
    return new PageResult(page,pagesize,count,list);
}

3.5 查看动态列表

tanhua-admin

tanhua-admin模块ManageControllerManagerService添加方法

ManageController
//查询动态
@GetMapping("/messages")
public ResponseEntity messages(@RequestParam(defaultValue = "1") Integer page,
                               @RequestParam(defaultValue = "10") Integer pagesize,
                               Long uid,Integer state) {
    PageResult result = managerService.findAllMovements(page,pagesize,uid,state);
    return ResponseEntity.ok(result);
}
ManagerService
//查询动态
public PageResult findAllMovements(Integer page, Integer pagesize, Long uid, Integer state) {
    //1、调用API查询数据 :Movment对象
    PageResult result = movementApi.findByUserId(uid,state,page,pagesize);
    //2、解析PageResult,获取Movment对象列表
    List<Movement> items = (List<Movement>) result.getItems();
    //3、一个Movment对象转化为一个Vo
    if(CollUtil.isEmpty(items)) {
        return new PageResult();
    }
    List<Long> userIds = CollUtil.getFieldValues(items, "userId", Long.class);
    Map<Long, UserInfo> map = userInfoApi.findByIds(userIds, null);
    List<MovementsVo> vos = new ArrayList<>();
    for (Movement movement : items) {
        UserInfo userInfo = map.get(movement.getUserId());
        if(userInfo != null) {
            MovementsVo vo = MovementsVo.init(userInfo, movement);
            vos.add(vo);
        }
    }
    //4、构造返回值
    result.setItems(vos);
    return result;
}

tanhua-dubbo-interface

tanhua-dubbo-interface中的MovementApi中定义根据用户ID分页查询用户发布的动态列表方法

/**
 * 根据用户ID分页查询用户发布的动态列表
 */
PageResult findByUserId(Long uid, Integer state, Integer page, Integer pagesize);

tanhua-dubbo-mongo

tanhua-dubbo-mongo中的MovementApi中实现根据用户ID分页查询用户发布的动态列表方法

@Override
public PageResult findByUserId(Long uid, Integer state, Integer page, Integer pagesize) {
    Query query = new Query();
    if(uid != null) {
        query.addCriteria(Criteria.where("userId").is(uid));
    }
    if(state != null) {
        query.addCriteria(Criteria.where("state").is(state));
    }
    //查询总数
    long count = mongoTemplate.count(query, Movement.class);
    //设置分页参数
    query.with(Sort.by(Sort.Order.desc("created"))).limit(pagesize).skip((page -1) * pagesize);

    List<Movement> list = mongoTemplate.find(query, Movement.class);
    return new PageResult(page,pagesize,count,list);
}

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

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

相关文章

33.数据统计

数据统计 后台系统首页中&#xff0c;显示各种统计数据&#xff0c;比如&#xff1a;累计用户数、新增用户数、登录次数等内容。 解决方案 数据库表分析 一、数据采集 需求&#xff1a; 1、探花系统将用户操作日志写入RabbitMQ 2、管理后台获取最新消息&#xff0c;构造日…

SpringBoot+微信小程序实现的云音乐小程序系统 附带详细运行指导视频

文章目录一、项目演示二、项目介绍三、项目运行截图四、主要代码一、项目演示 项目演示地址&#xff1a; 视频地址 二、项目介绍 项目描述&#xff1a;这是一个基于SpringBoot微信小程序框架开发的云音乐微信小程序系统。首先&#xff0c;这是一个前后端分离的项目&#xff…

C语言百日刷题第十五天

前言 今天是刷题第15天&#xff0c;放弃不难&#xff0c;但坚持一定很酷~ 再刷一套模拟题 C语言百日刷题第十五天前言一、选择题二、判断题三、多选题四、填空题五、分析程序题一、选择题 1.下列选项中&#xff0c;不属于开发一个C语言应用程序的具体实现步骤的是&#xf…

为什么网络应用程序是今年的主要攻击媒介之一

网络犯罪分子在绕过最新的网络应用程序防火墙方面的独创性正在将互联网应用程序变成今年增长最快的攻击媒介。面向公众的 Web 应用程序现在是渗透组织边界的最广泛使用的攻击媒介。 根据卡巴斯基全球应急响应团队最近的一份报告&#xff0c;始于 Web 应用程序的攻击从 2020 年…

ocker高级篇1-dockeran安装mysql主从复制

大家好&#xff0c;咱们前面通过十篇的文章介绍了docker的基础篇&#xff0c;从本篇开始&#xff0c;咱们的《docker学习系列》将要进入到高级篇阶段(基础篇大家可以查看之前发布的文章)。 咱们先来介绍&#xff1a;docker复杂方式安装软件。通过按照mysql\redis两个案例来讲解…

XC6SLX100-3FGG484C规格、XC7A15T-2CPG236I产品概述及应用

Spartan-6系列提供领先的系统集成能力&#xff0c;为大批量应用提供最低的总成本。这个由13个成员组成的家族扩展了逻辑单元的密度&#xff0c;从3840个扩展到147443个&#xff0c;功耗仅为之前斯巴达家族的一半&#xff0c;并且具有更快、更全面的连接。 Spartan-6系列基于成熟…

拯救动画卡顿之FLIP

前置知识 什么是FPS FPS是浏览器的每秒的渲染帧数&#xff0c;也就是浏览器切换画面的次数&#xff0c;大多数设备的刷新率都是60FPS&#xff0c;一般来说FPS越低页面就会越卡顿。 什么是像素管道&#xff1f; 像素管道是浏览器单个帧的渲染流水线&#xff0c;如果其中有某…

vue数据双向绑定

5.Vue数据双向绑定 5.1.什么是双向数据绑定 Vue.js 是一个 MVVM 框架&#xff0c;即数据双向绑定&#xff0c;即当数据发生变化的时候&#xff0c;视图也就发生变化&#xff0c;当视图发生变化的时候&#xff0c;数据也会跟着同步变化。这也算是 Vue.js 的精髓之处了。 值得…

[ MessAuto ]: 短信验证码自动填充,理论支持所有浏览器或 APP, Only For Mac

MessAuto 开源地址&#xff1a;https://github.com/LeeeSe/MessAuto MessAuto 是一款 macOS 平台 自动提取 短信验证码并 粘贴回车 的软件&#xff0c;百分百由Rust开发&#xff0c;适用于任何APP。 特点&#xff1a; 轻量&#xff1a;程序占用存储 1.8 M&#xff0c;占用内…

NLP学习笔记(三) GRU基本介绍

大家好&#xff0c;我是半虹&#xff0c;这篇文章来讲门控循环单元 (Gated Recurrent Unit, GRU) 文章行文思路如下&#xff1a; 首先通过长短期记忆网络引出为什么需要门控循环单元然后介绍门控循环单元的核心思想与运作方式最后通过简洁的代码深入理解门控循环单元的运作方…

奇舞周刊 476 期:代码在内存中的 “形状”

记得点击文章末尾的“ 阅读原文 ”查看哟~下面先一起看下本期周刊 摘要 吧~奇舞推荐■ ■ ■代码在内存中的 “形状”众所周知&#xff0c;js 的基本数据类型有 number、string、boolean、null、undefined 等。那么问题来了 typeof null 和 typeof undefined 分别是什么呢&…

[附源码]Node.js计算机毕业设计果蔬预约种植管理系统Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

[内网渗透]—NTLM网络认证及NTLM-Relay攻击

NTML网络认证 Windows认证分为本地认证和网络认证,当我们开机登录用户账户时,就需要将lsass.exe进程转换的明文密码hash与 sam文件进行比对,这种方式即为——本地认证 而当我们访问同一局域网的一台主机上的SMB共享时,需要提供凭证通过验证才能访问,这个过程就会设计win…

【C++】list 的模拟实现

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《吃透西嘎嘎》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录&#x1f449;前言&…

Halcon条码和二维码质量评级

现在各行各业的人们都使用条码/二维码从生产阶段到销售点全程追踪他们 的产品。那么怎么验证生产出来的具有可读性&#xff0c;码的质量等级如何呢&#xff1f; 其实ISO行业标准已经给出了如何评估码的质量等级的标准&#xff0c;以下三种主要验证标准用于确定一维条码、二维码…

毕业设计 - 基于Java EE平台项目管理系统的设计与实现【源码+论文】

文章目录前言一、项目设计1. 模块设计2. 实现效果二、部分源码项目工程前言 今天学长向大家分享一个 java web项目: 基于Java EE平台项目管理系统的设计与实现 一、项目设计 1. 模块设计 从管理员角度看: 用户登入系统后&#xff0c;可以修改管理员的密码。同时具有以下功能…

最全的SpringMVC教程,终于让我找到了

1. 为啥要学 SpringMVC&#xff1f; 1.1 SpringMVC 简介 在学习 SpringMVC 之前我们先看看在使用 Servlet 的时候我们是如何处理用户请求的&#xff1a; 配置web.xml <?xml version"1.0" encoding"UTF-8"?> <web-app xmlns"http://xmln…

[附源码]Python计算机毕业设计国际美容会所管理系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

Jetpack Compose中的动画

Jetpack Compose中没有沿用Android原有的View动画和属性动画&#xff0c;而是新创建了一套全新的动画系统API&#xff0c;这是理所当然的&#xff0c;因为旧的动画系统主要是基于View体系的&#xff0c;而Compose中需要针对的是Composable可组合函数进行处理&#xff0c;那么势…

他文献查到凌晨两点,我用Python十分钟搞定!

大家好&#xff0c;我是爱学习的王饱饱。 对于应届毕业生来说&#xff0c;今年一定是难熬的一年。本来找工作、写论文就已经是两座大山了&#xff0c;还要面临论文无指导的额外压力。 这让我想到了去年毕业的表弟&#xff0c;当时他为了完成论文&#xff0c;摔烂了三个鼠标。…