谷粒学院——第十二章、Banner轮播图

news2024/9/25 17:20:02

Banner微服务

配置 Nginx

修改文件:nginx.conf
image.png
修改完后,重启 nginx

nginx -s reload

创建项目和初始化

1、新建模块

service_cms

2、配置文件和启动类

创建配置文件:application.properties

# 服务端口
server.port=8004

# 服务名
spring.application.name=service-cms

# mysql数据库连接
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/guli?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=root

#返回json的全局时间格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8

#配置mapper xml文件的路径
mybatis-plus.mapper-locations=classpath:com/atguigu/educms/mapper/xml/*.xml

#mybatis日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

创建包org.jyunkai.educms,启动类CmsApplication

@SpringBootApplication
@ComponentScan({"com.atguigu"})
@MapperScan("com.atguigu.educms.mapper")
public class CmsApplication {
    public static void main(String[] args) {
        SpringApplication.run(CmsApplication.class, args);
    }
}

3、代码生成器

复制service_edu模块中的CodeGenerator类,更改模块名称为educms,更改表名为crm_banner,运行即可。

public class CodeGenerator {

    @Test
    public void run() {

        // 1、创建代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // 2、全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir("D:\\java\\springcloud\\guli_xueyuan\\guli_parent\\service\\service_cms" + "/src/main/java");

        gc.setAuthor("testjava");
        gc.setOpen(false); //生成后是否打开资源管理器
        gc.setFileOverride(false); //重新生成时文件是否覆盖

        //UserServie
        gc.setServiceName("%sService");	//去掉Service接口的首字母I

        gc.setIdType(IdType.ID_WORKER_STR); //主键策略
        gc.setDateType(DateType.ONLY_DATE);//定义生成的实体类中日期类型
        gc.setSwagger2(true);//开启Swagger2模式

        mpg.setGlobalConfig(gc);

        // 3、数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/guli?serverTimezone=GMT%2B8");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("root");
        dsc.setDbType(DbType.MYSQL);
        mpg.setDataSource(dsc);

        // 4、包配置
        PackageConfig pc = new PackageConfig();
        pc.setModuleName("educms"); //模块名
        //包  com.atguigu.eduservice
        pc.setParent("com.atguigu");
        //包  com.atguigu.eduservice.controller
        pc.setController("controller");
        pc.setEntity("entity");
        pc.setService("service");
        pc.setMapper("mapper");
        mpg.setPackageInfo(pc);

        // 5、策略配置
        StrategyConfig strategy = new StrategyConfig();

        strategy.setInclude("crm_banner");

        strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略
        strategy.setTablePrefix(pc.getModuleName() + "_"); //生成实体时去掉表前缀

        strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略
        strategy.setEntityLombokModel(true); // lombok 模型 @Accessors(chain = true) setter链式操作

        strategy.setRestControllerStyle(true); //restful api风格控制器
        strategy.setControllerMappingHyphenStyle(true); //url中驼峰转连字符

        mpg.setStrategy(strategy);


        // 6、执行
        mpg.execute();
    }
}

创建banner后台管理接口

banner 后台分页查询、添加、修改、删除接口

controller层

删除 CrmBannerController,新建后台管理接口:

@RestController
@RequestMapping("/educms/banneradmin")
@CrossOrigin
public class BannerAdminController {

    @Autowired
    private CrmBannerService bannerService;

    @ApiOperation(value = "获取Banner分页列表")
    @GetMapping("pageBanner/{page}/{limit}")
    public R pageBanner(
            @ApiParam(name = "page", value = "当前页码", required = true)
            @PathVariable("page") Long page,
            @ApiParam(name = "limit", value = "每页记录数", required = true)
            @PathVariable("limit") Long limit) {
        Page<CrmBanner> pageBanner = new Page<>(page, limit);
        bannerService.page(pageBanner, null);
        return R.ok().data("items", pageBanner.getRecords()).data("total", pageBanner.getTotal());
    }

    @ApiOperation(value = "获取Banner")
    @GetMapping("get/{id}")
    public R get(@PathVariable("id") String id) {
        CrmBanner banner = bannerService.getBannerById(id);
        return R.ok().data("item", banner);
    }

    @ApiOperation(value = "新增Banner")
    @PostMapping("save")
    public R save(@RequestBody CrmBanner banner) {
        bannerService.saveBanner(banner);
        return R.ok();
    }

    @ApiOperation(value = "修改Banner")
    @PutMapping("update")
    public R updateById(@RequestBody CrmBanner banner) {
        bannerService.updateBannerById(banner);
        return R.ok();
    }

    @ApiOperation(value = "删除Banner")
    @DeleteMapping("remove/{id}")
    public R remove(@PathVariable("id") String id) {
        bannerService.removeBannerById(id);
        return R.ok();
    }
}

创建banner前台管理接口

controller层

创建类BannerFrontController

@RestController
@RequestMapping("/educms/bannerfront")
@CrossOrigin
public class BannerFrontController {

    @Autowired
    private CrmBannerService bannerService;

    @ApiOperation(value = "查询所有的banner")
    @GetMapping("getAllBanner")
    public R getAllBanner() {
        List<CrmBanner> list = bannerService.selectAllBanner();
        return R.ok().data("list", list);
    }
}

service层

public interface CrmBannerService extends IService<CrmBanner> {
    // 查询所有的banner
    List<CrmBanner> selectAllBanner();
}

实现类

@Service
public class CrmBannerServiceImpl extends ServiceImpl<CrmBannerMapper, CrmBanner> implements CrmBannerService {

    // 查询所有的banner
    @Override
    public List<CrmBanner> selectAllBanner() {
        // 根据id进行降序排列,显示排列后前两条记录
        QueryWrapper<CrmBanner> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("id");
        // last方法拼接sql语句
        wrapper.last("limit 2");
        List<CrmBanner> list = baseMapper.selectList(null);
        return list;
    }
}

前端查询课程名师接口

在 service_edu 模块

controller层

创建front包,然后创建IndexFrontController类:

@RestController
@RequestMapping("/eduservice/indexfront")
@CrossOrigin
public class IndexFrontController {

    @Autowired
    private EduCourseService courseService;

    @Autowired
    private EduTeacherService teacherService;

    /*
    查询前8条热门课程,前4条热门名师
     */
    @GetMapping("index")
    public R index() {
        QueryWrapper<EduCourse> courseWrapper = new QueryWrapper<>();
        courseWrapper.orderByDesc("id");
        courseWrapper.last("limit 8");
        List<EduCourse> courseList = courseService.list(courseWrapper);

        QueryWrapper<EduTeacher> teacherWrapper = new QueryWrapper<>();
        teacherWrapper.orderByDesc("id");
        teacherWrapper.last("limit 4");
        List<EduTeacher> teacherList = teacherService.list(teacherWrapper);
        return R.ok().data("courseList", courseList).data("teacherList", teacherList);
    }
}

前端部分

1、js

在根目录下创建一个api文件夹,在里面新建 banner.js 和 index.js
banner.js:

import request from '../utils/request'

export default {
  // 查询前两条 banner 数据
  getListBanner() {
    return request({
      url: '/educms/bannerfront/getAllBanner',
      method: 'get'
    })
  }
}

index.js:

import request from '../utils/request'

export default {
  // 查询热门课程和名师
  getIndexData() {
    return request({
      url: '/eduservice/indexfront/index',
      method: 'get'
    })
  }
}

2、pages/index.vue

定义和调用方法

<script>
import banner from '../api/banner'
import index from '../api/index'

export default {
  data() {
    return {
      swiperOption: {
        //配置分页
        pagination: {
          el: '.swiper-pagination'//分页的dom节点
        },
        //配置导航
        navigation: {
          nextEl: '.swiper-button-next',//下一页dom节点
          prevEl: '.swiper-button-prev'//前一页dom节点
        }
      },
      //banner数组
      bannerList: [],
      eduList: [],
      teacherList: []
    }
  },
  created() {
    //调用查询banner的方法
    this.getBannerList()
    //调用查询热门课程和名师的方法
    this.getHotCourseTeacher()
  },
  methods: {
    //查询热门课程和名师
    getHotCourseTeacher() {
      index.getIndexData()
        .then(response => {
          this.eduList = response.data.data.eduList
          console.log(this.eduList)
          this.teacherList = response.data.data.teacherList
        })
    },
    //查询banner数据
    getBannerList() {
      banner.getListBanner()
        .then(response => {
          this.bannerList = response.data.data.list
        })
    }
  }
}
</script>

显示banner

修改数据库crm_banner表中的测试图片banner的链接:
http://guli.shop/photo/banner/1525939573202.jpg
http://guli.shop/photo/course/02.jpg
image.png
修改幻灯片播放代码:

<!-- 幻灯片 开始 -->
<div class="swiper-wrapper">
  <div v-for="banner in bannerList" :key="banner.id" class="swiper-slide" style="background: #040B1B;">
    <a :href="banner.linkUrl" target="_blank">
      <img :src="banner.imageUrl" :alt="banner.title">
    </a>
  </div>
</div>
<!-- 幻灯片 结束 -->

课程列表部分(这里我加入了评论数和价格)
删去其它

  • 标签,只保留一个
  • <li v-for="course in eduList" :key="course.id">
      <div class="cc-l-wrap">
        <section class="course-img">
          <img :src="course.cover" class="img-responsive" :alt="course.title"
            style="width: 267.5px; height: 180px;">
          <div class="cc-mask">
            <a :href="'/course/' + course.id" title="开始学习" class="comm-btn c-btn-1">开始学习</a>
          </div>
        </section>
        <h3 class="hLh30 txtOf mt10">
          <a :href="'/course/' + course.id" :title="course.title" class="course-title fsize18 c-333">{{ course.title }}</a>
        </h3>
        <section class="mt10 hLh20 of">
          <span class="fr jgTag bg-green" v-if="Number(course.price) === 0">
            <i class="c-fff fsize18 f-fA">免费</i>
          </span>
          <span class="fr jgTag bg-green" v-else style="background-color: red;">
            <i class="c-fff fsize18 f-fA">¥{{ course.price }}</i>
          </span>
          <span class="fl jgAttr c-ccc f-fA">
            <i class="c-999 f-fA">{{ course.viewCount }}人学习</i>
            |
            <i class="c-999 f-fA">{{ course.commentCount }}人评论</i>
          </span>
        </section>
      </div>
    </li>
    

    讲师列表部分
    删去其它

  • 标签,只保留一个
  • <li v-for="teacher in teacherList" :key="teacher.id">
      <section class="i-teach-wrap">
        <div class="i-teach-pic">
          <a :title="teacher.name" href="/teacher/1">
            <img :alt="teacher.name" :src="teacher.avatar" style="height: 141.3px">
          </a>
        </div>
        <div class="mt10 hLh30 txtOf tac">
          <a :title="teacher.name" href="/teacher/1" class="fsize18 c-666">{{ teacher.name }}}</a>
        </div>
        <div class="hLh30 txtOf tac">
          <span class="fsize14 c-999">{{ teacher.career }}}</span>
        </div>
        <div class="mt15 i-q-txt">
          <p class="c-999 f-fA">{{ teacher.intro }}</p>
        </div>
      </section>
    </li>
    

    配置 Redis 缓存

    Redis 是当前比较热门的 NOSQL 技术之一,它是一个开源的使用ANSI C语言编写的 key-value 存储系统 (区别于 MySQL 的二维表格的形式存储。)。和 Memcache 类似,但很大程度补偿了 Memcache 的不足。和Memcache一样,Redis数据都是缓存在计算机内存中,不同的是,Memcache只能将数据缓存到 内存中,无法自动定期写入硬盘,这就表示,一断电或重启,内存清空,数据丢失。所以Memcache的 应用场景适用于缓存无需持久化的数据。而Redis不同的是它会周期性的把更新的数据写入磁盘或者把修 改操作写入追加的记录文件,实现数据的持久化。

    Redis的特点:
    1,Redis读取的速度是110000次/s,写的速度是81000次/s;
    2,原子 。Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。
    3,支持多种数据结构:string(字符串);list(列表);hash(哈希),set(集合);zset(有序集合)
    4,持久化,集群部署
    5,支持过期时间,支持事务,消息订阅

    创建配置类

    由于redis缓存是公共应用,所以我们把依赖与配置添加到了common模块下面,在common模块pom.xml下添加以下依赖

    <!-- redis -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <!-- spring2.X集成redis所需common-pool2 -->
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-pool2</artifactId>
      <version>2.6.0</version>
    </dependency>
    

    在 service_base 模块的包 config 下面创建类:

    @Configuration // 开启缓存
    @EnableCaching
    public class RedisConfig extends CachingConfigurerSupport {
        @Bean
        public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
            RedisTemplate<String, Object> template = new RedisTemplate<>();
            RedisSerializer<String> redisSerializer = new StringRedisSerializer();
            Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
            ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            jackson2JsonRedisSerializer.setObjectMapper(om);
            template.setConnectionFactory(factory);
            //key序列化方式
            template.setKeySerializer(redisSerializer);
            //value序列化
            template.setValueSerializer(jackson2JsonRedisSerializer);
            //value hashmap序列化
            template.setHashValueSerializer(jackson2JsonRedisSerializer);
            return template;
        }
    
        @Bean
        public CacheManager cacheManager(RedisConnectionFactory factory) {
            RedisSerializer<String> redisSerializer = new StringRedisSerializer();
            Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
            //解决查询缓存转换异常的问题
            ObjectMapper om = new ObjectMapper();
            om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            jackson2JsonRedisSerializer.setObjectMapper(om);
            // 配置序列化(解决乱码的问题),过期时间600秒
            RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                    .entryTtl(Duration.ofSeconds(600))
                    .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                    .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                    .disableCachingNullValues();
            RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                    .cacheDefaults(config)
                    .build();
            return cacheManager;
        }
    }
    

    在接口中使用 redis

    在查询所有banner的方法上面添加缓存注解:

    **(1)缓存@Cacheable **
    根据方法对其返回结果进行缓存,下次请求时,如果缓存存在,则直接读取缓存数据返回;如果缓存不存在,则执行方法,并把返回的结果存入缓存中。一般用在查询方法上。
    查看源码,属性值如下:
    image.png
    **(2)缓存@CachePut **
    使用该注解标志的方法,每次都会执行,并将结果存入指定的缓存中。其他方法可以直接从响应的缓存中读取缓存数据,而不需要再去查询数据库。一般用在新增方法上。
    查看源码,属性值如下:
    image.png
    **(3)缓存@CacheEvict **
    使用该注解标志的方法,会清空指定的缓存。一般用在更新或者删除方法上
    查看源码,属性值如下:
    image.png

    首页数据添加 redis 缓存

    在 service_cms 模块中controller层中:
    注意不要引用错包:import org.springframework.cache.annotation.Cacheable
    image.png

    修改配置文件

    在 service_cms 的配置文件中,配置 redis

    # 配置 redis
    spring.redis.host=127.0.0.1
    spring.redis.port=6379
    spring.redis.database=0
    spring.redis.timeout=1800000
    spring.redis.lettuce.pool.max-active=20
    spring.redis.lettuce.pool.max-wait=-1
    spring.redis.lettuce.pool.max-idle=5
    spring.redis.lettuce.pool.min-idle=0
    

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

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

相关文章

电子招标采购系统源码之从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。

统一供应商门户 便捷动态、呈现丰富 供应商门户具备内外协同的能力&#xff0c;为外部供应商集中推送展示与其相关的所有采购业务信息&#xff08;历史合作、考察整改&#xff0c;绩效评价等&#xff09;&#xff0c;支持供应商信息的自助维护&#xff0c;实时风险自动提示。…

互联网还会回暖吗?蛮三刀酱的2022年终技术总结

靠近年底的月份&#xff0c;内心深处总会不断提醒你&#xff0c;该写年终总结了。无论是工作上&#xff0c;生活上&#xff0c;亦或是互联网、APP上&#xff0c;无数的年终报告提醒我&#xff0c;一年了也该总结一下自己了&#xff0c;不然这之前的1年是不是白过了呢&#xff1…

Vue组件之间的通信(二)

一、兄弟组件之间的通信 &#xff08;1&#xff09;使用Vue的状态管理器Vue&#xff1a;建议在大型项目中使用 &#xff08;2&#xff09;使用第三方的模块&#xff1a;mitt(中央数据总线方式)&#xff0c;创建一个事件中心&#xff0c;由它来进行事件的监听、触发&#xff0…

第一章算法简介

二分查找引入大O表示法 仅知道算法需要多长时间运行完毕还不够&#xff0c;还需要知道运行时间如何随列表长度增加而增加&#xff0c;这正是大O表示法的用武之地。 大O表示法 大O表示法指出了算法有多块&#xff0c;之所以称作大O&#xff0c;单纯因为前面有个O(funny!)大O表…

Allegro174版本新功能介绍之导入导出菜单栏设置

Allegro174版本新功能介绍之导入导出菜单栏设置 Allegro174版本除了支持锁定菜单栏设置之外,同样还支持导出和导入菜单栏的设置 具体操作如下 首先设置并且排列好菜单栏,类似下图选

基于链表的通信录管理

意义&#xff1a;对于一个通信录来说&#xff0c;要管理联系人的信息&#xff0c;包括编号&#xff0c;姓名&#xff0c;性别&#xff0c;电话。开发其系统主要为了帮助用户提高通讯录有管理效率&#xff0c;节约资源&#xff0c;提高信息的精确度模块&#xff1a;一级菜单内容…

【Go基础】数据类型

文章目录1. 数据类型1.1 基本数据类型1.2 复合数据类型1.3 自定义数据类型2. 数组3. 切片4. 字符串5. 数据类型转换6. Map7. Channel1. 数据类型 1.1 基本数据类型 类型长度(字节)默认值说明bool1falsebyte10uint8&#xff0c;取值范围[0,255]rune40Unicode Code Point, int3…

电脑解压文件丢失怎么找回来?四种恢复方法

您在使用电脑过程中&#xff0c;有没有解压过文件呢&#xff1f;如果有的话&#xff0c;是否出现过解压文件丢失的情况呢&#xff1f;解压文件通俗易懂地讲就是把压缩好了的文件解开。而有些小伙伴在解压文件以后发现丢失了&#xff0c;这些丢失的文件或许是您重要的img解压文件…

数学建模学习笔记-算法(求解整数规划-2.割平面算法)

基本思想 松弛问题无解&#xff0c;则整数规划无解 松弛问题的最优解是整数解&#xff0c;则他也是整数规划的最优解 如果松弛问题的解是非整数解&#xff0c;则对其增加割平面条件。 割平面条件&#xff1a;增加一个线性条件&#xff0c;通过不等式将可行区域割掉一部分&a…

如何使用ebpf统计某个端口的流量

前言 上篇文章我们已经初步使用kprobe来探测内核函数了, 这篇文章就在上篇文章的基础上做个修改, 通过kprobe探测内核函数tcp_sendmsg来统计tcp服务端的发送流量. 废话不多说, 直接上正文. 环境 tcp服务端运行在ubuntu22, 监听端口为6230, 其内核为5.19.0-26-generic, ebpf程序…

LSA、pLSA、LDA、NMF、BERTopic、Top2Vec进行主题建模

在自然语言处理(NLP)中,主题建模是一种技术,用于从文本数据中发现隐藏的语义主题(或主题)。这是一个无监督机器学习问题,即在没有标签或标签的情况下学习模式。主题建模的应用非常广泛,可用于搜索引擎、情感分析、新闻聚类和摘要生成等许多任务。 在这里将探讨主题建模…

一屏统管 智慧交管Web3D可视化大屏云控系统

交通是城市发展的基础&#xff0c;体现着社会文明程度&#xff0c;彰显着城市治理水平。今天给大家分享一个基于 数维图 的 Sovit3D编辑器 构建轻量化 3D 可视化场景的案例——智慧交管三维可视化系统。多维度呈现城市交通情况&#xff0c;赋能“安全管控、缓堵保畅、出行服务”…

硬件系统工程师宝典(2)-----硬件电路的概要设计启动

今天我们继续来读这本书&#xff0c;硬件系统工程师宝典。作者提到&#xff0c;产品需求分析之后就进入概要设计阶段。在这个阶段&#xff0c;ID&#xff08;Industrial Design&#xff09;工业设计及结构工程师、软件系统开发工程师和硬件系统开发工程师等开始分头工作。 工业…

头条百科词条怎么编辑?送你一份超详细指南

头条百科其实就是之前的互动百科&#xff0c;后面被今日头条收购之后&#xff0c;改为头条百科&#xff0c;也叫快懂百科。 百度百科在百度上的权重很高&#xff0c;而头条百科在今日头条和抖音上的权重很高。 现在我们遇到什么问题或是不知道什么人物、品牌的时候&#xff0…

xxljob 的 阻塞处理策略的逻辑是什么(小白)

目录 1 需求2 单机串行3 丢弃后续调整4 覆盖之前的调整1 需求 每一个任务都有一个阻塞处理策略,我们在创建任务的时候可以自己设置,那么不同的设置,后端的逻辑是什么呢》 xxljob 调度中心项目 调度我们自己的项目,到了我们项目里面,最先到的文件是 就在首次到的这个文件的…

Springboot-数据库操作(Mybatis)-初级入门

一、Mybatis-plus介绍 官方文档&#xff1a;简介 | MyBatis-Plus (baomidou.com) 他只增强了单表查询&#xff0c;没增强多表查询等复杂的查询。 二、配置 引入依赖 <!-- MyBatisPlus依赖--><dependency><groupId>com.baomidou</groupId><a…

UBUNTU 22.04 使用 SUNSHINE 和 MOONLIGHT 进行串流

参考 【ubuntu22.04】sunshine安装使用总结&#xff0c;远程游戏。_哔哩哔哩_bilibili sunshine/README.md at master loki-47-6F-64/sunshine GitHub GitHub - LizardByte/Sunshine: Sunshine is a Gamestream host for Moonlight. Installation - Sunshine documentati…

基于Java+SpringBoot+vue实现图书借阅和销售商城一体化系统

基于JavaSpringBootvue实现图书借阅和销售商城一体化系统 &#x1f680; 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 &#x1f345; 作者主页 超级帅帅吴 &#x1f345; 欢迎点赞 &#x1f…

2023年江苏专转本志愿填报辅导(22上岸南工程学长辅导手册)

文章目录公告链接一、23年专转本与22年的变化二、专转本志愿填报2.1、填报流程2.2、志愿填报院校顺序选择参考三、专转本考试分值及时间节点四、专转本录取投档原则及办法&#xff08;平行、征求平行志愿、服从志愿、降分录取&#xff09;五、考前冲刺辅导不同大类填报计算机大…

面试官问我TCP三次握手和四次挥手,我真的是

候选者&#xff1a;面试官你好&#xff0c;请问面试可以开始了吗 面试官&#xff1a;嗯&#xff0c;开始吧 面试官&#xff1a;今天来聊聊TCP吧&#xff0c;TCP的各个状态还有印象吗&#xff1f; 候选者&#xff1a;还有些许印象的&#xff0c;要不我就来简单说下TCP的三次握…