Spring Boot 3.2 + Vue 3 图书馆管理系统实战:5大核心模块与8张数据库表设计

#每天一道ACM_8.8(给草坪装洒水装置) 喷水装置【一】 题目来源于网上,南阳理工大学的acm练习 描述 现有一块草坪,长为20米,宽为2米,要在横中心线上放置半径为Ri的喷水装置,每个喷水装置的效果都会让以它为中心的半径为实数Ri(0 输入 第一行m表示有m组测试数据 每一组测试数据的第一行有一个整数数n,n表示共有n个喷水装置,随后的一行,有n个实数ri,ri表示该喷水装置能覆盖的圆的半径。 输出 输出所用装置... 阅读详情

Spring Boot 3.2 + Vue 3 图书馆管理系统实战:5大核心模块与8张数据库表设计

在数字化转型浪潮下,传统图书馆管理系统正面临技术架构升级的迫切需求。本文将基于Spring Boot 3.2和Vue 3这一黄金技术组合,带你从零构建一个现代化图书馆管理系统。不同于传统理论分析,我们将聚焦工程化实现,通过清晰的代码示例和架构设计,帮助初中级开发者掌握企业级应用开发的核心要领。

1. 技术栈选型与项目初始化

1.1 现代技术栈优势分析

选择Spring Boot 3.2和Vue 3的组合并非偶然,这一技术搭配在2023年全栈开发领域展现出显著优势:

  • 后端技术栈 :

    • Spring Boot 3.2:内置Tomcat 10支持,提供GraalVM原生镜像编译能力
    • MyBatis-Plus 3.5.3:简化CRUD操作,动态SQL生成
    • Spring Security 6:OAuth2资源服务器配置
    • Hibernate Validator 8:参数校验标准化
  • 前端技术栈 :

    • Vue 3.3 + Composition API:更好的TypeScript支持
    • Pinia 2:状态管理解决方案
    • Element Plus 2.3:UI组件库
    • Axios 1.3:HTTP客户端
# 后端项目初始化
spring init --dependencies=web,mybatis,security,validation 
  -g com.library -a library-backend -n library-backend

# 前端项目初始化
npm create vue@latest library-frontend

1.2 项目结构设计

合理的项目结构是大型应用的基础,我们采用分层架构设计:

library-system/
├── backend/               # Spring Boot项目
│   ├── src/
│   │   ├── main/
│   │   │   ├── java/com/library/
│   │   │   │   ├── config/       # 配置类
│   │   │   │   ├── controller/   # 控制器层
│   │   │   │   ├── dto/          # 数据传输对象
│   │   │   │   ├── entity/       # 数据库实体
│   │   │   │   ├── mapper/       # MyBatis接口
│   │   │   │   ├── service/      # 业务逻辑层
│   │   │   │   └── util/         # 工具类
│   │   │   └── resources/
│   │   │       ├── mapper/       # XML映射文件
│   │   │       └── application.yml
├── frontend/              # Vue项目
│   ├── src/
│   │   ├── api/           # API请求封装
│   │   ├── assets/        # 静态资源
│   │   ├── components/    # 公共组件
│   │   ├── router/        # 路由配置
│   │   ├── stores/        # Pinia状态管理
│   │   ├── styles/        # 全局样式
│   │   ├── utils/         # 工具函数
│   │   └── views/         # 页面组件
└── docs/                  # 项目文档

2. 核心业务模块设计

2.1 用户认证模块

采用JWT作为认证方案,实现多角色权限控制:

// Spring Security配置核心代码
@Configuration
@EnableWebSecurity
public class SecurityConfig {
    
    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf(AbstractHttpConfigurer::disable)
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/auth/**").permitAll()
                .requestMatchers("/api/admin/**").hasRole("ADMIN")
                .requestMatchers("/api/librarian/**").hasAnyRole("LIBRARIAN", "ADMIN")
                .anyRequest().authenticated()
            )
            .sessionManagement(session -> 
                session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .addFilterBefore(jwtFilter(), UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }
    
    @Bean
    JwtAuthenticationFilter jwtFilter() {
        return new JwtAuthenticationFilter();
    }
}

前端路由守卫实现:

// 路由权限控制
router.beforeEach((to, from, next) => {
  const authStore = useAuthStore()
  const requiresAuth = to.matched.some(record => record.meta.requiresAuth)
  const requiredRoles = to.meta.roles || []

  if (requiresAuth && !authStore.isAuthenticated) {
    next('/login')
  } else if (requiredRoles.length && !requiredRoles.includes(authStore.user.role)) {
    next('/403')
  } else {
    next()
  }
})

2.2 图书管理模块

实现图书的CRUD操作及复杂查询功能,采用MyBatis-Plus增强功能:

@Service
public class BookServiceImpl extends ServiceImpl<BookMapper, Book> 
    implements BookService {
    
    @Override
    public Page<BookVO> searchBooks(BookQueryDTO queryDTO) {
        return lambdaQuery()
            .like(StringUtils.hasText(queryDTO.getTitle()), Book::getTitle, queryDTO.getTitle())
            .like(StringUtils.hasText(queryDTO.getAuthor()), Book::getAuthor, queryDTO.getAuthor())
            .eq(queryDTO.getCategoryId() != null, Book::getCategoryId, queryDTO.getCategoryId())
            .eq(Book::getStatus, BookStatus.AVAILABLE)
            .page(queryDTO.toPage())
            .convert(this::toVO);
    }
    
    private BookVO toVO(Book book) {
        // 对象转换逻辑
    }
}

前端采用组合式API实现分页查询:

<script setup>
const searchForm = reactive({
  title: '',
  author: '',
  category: null
})

const { data, pending, execute } = useAsyncData(
  'books',
  () => $fetch('/api/books', {
    query: {
      ...searchForm,
      page: pagination.value.page,
      size: pagination.value.size
    }
  })
)

const pagination = reactive({
  page: 1,
  size: 10,
  total: 0
})

watchDebounced(
  searchForm,
  () => {
    pagination.page = 1
    execute()
  },
  { debounce: 500 }
)
</script>

3. 数据库设计与优化

3.1 核心表结构设计

系统共设计8张核心表,关系模型如下:

表名 主要字段 说明
book id, isbn, title, author, status 图书基本信息
book_category id, name, parent_id 图书分类
user id, username, password, role 系统用户
borrower id, user_id, card_number 借阅者信息
borrow_record id, book_id, borrower_id, status 借阅记录
reservation id, book_id, borrower_id, expire 预约记录
fine id, record_id, amount, status 罚款记录
system_log id, user_id, operation, time 系统操作日志

3.2 索引优化策略

针对高频查询场景设计索引:

-- 图书表索引
CREATE INDEX idx_book_title ON book(title);
CREATE INDEX idx_book_author ON book(author);
CREATE INDEX idx_book_status ON book(status);

-- 借阅记录索引
CREATE INDEX idx_borrow_borrower ON borrow_record(borrower_id);
CREATE INDEX idx_borrow_book ON borrow_record(book_id);
CREATE INDEX idx_borrow_status ON borrow_record(status);

-- 复合索引示例
CREATE INDEX idx_book_search ON book(title, author, status);

3.3 事务处理示例

借书业务中的事务控制:

@Transactional
public BorrowResult borrowBook(Long bookId, Long borrowerId) {
    // 1. 检查图书状态
    Book book = bookMapper.selectById(bookId);
    if (book == null || book.getStatus() != BookStatus.AVAILABLE) {
        return BorrowResult.failed("图书不可借");
    }
    
    // 2. 检查借阅者资格
    Borrower borrower = borrowerMapper.selectById(borrowerId);
    if (borrower == null || borrower.getStatus() != BorrowerStatus.ACTIVE) {
        return BorrowResult.failed("借阅者状态异常");
    }
    
    // 3. 创建借阅记录
    BorrowRecord record = new BorrowRecord();
    record.setBookId(bookId);
    record.setBorrowerId(borrowerId);
    record.setBorrowDate(LocalDate.now());
    record.setDueDate(LocalDate.now().plusDays(30));
    record.setStatus(BorrowStatus.ON_LOAN);
    borrowRecordMapper.insert(record);
    
    // 4. 更新图书状态
    book.setStatus(BookStatus.BORROWED);
    bookMapper.updateById(book);
    
    return BorrowResult.success(record);
}

4. 前后端交互设计

4.1 API规范设计

采用RESTful风格设计API接口:

资源 GET POST PUT DELETE
/api/books 获取图书列表 新增图书 - -
/api/books/{id} 获取图书详情 - 更新图书信息 删除图书
/api/borrow 查询借阅记录 借书操作 还书操作 -
/api/reservations 查询预约记录 创建预约 取消预约 -

4.2 Axios封装示例

前端请求统一封装:

// api/request.js
const service = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL,
  timeout: 10000
})

// 请求拦截器
service.interceptors.request.use(config => {
  const authStore = useAuthStore()
  if (authStore.token) {
    config.headers.Authorization = `Bearer ${authStore.token}`
  }
  return config
})

// 响应拦截器
service.interceptors.response.use(
  response => {
    return response.data
  },
  error => {
    if (error.response?.status === 401) {
      const authStore = useAuthStore()
      authStore.logout()
      router.push('/login')
    }
    return Promise.reject(error)
  }
)

export default service

4.3 WebSocket实时通知

实现图书逾期提醒功能:

// WebSocket配置
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws")
                .setAllowedOriginPatterns("*")
                .withSockJS();
    }
}

// 通知服务
@Service
@RequiredArgsConstructor
public class NotificationService {
    
    private final SimpMessagingTemplate messagingTemplate;
    
    public void sendOverdueNotice(Long borrowerId, String message) {
        messagingTemplate.convertAndSend(
            "/topic/user/" + borrowerId,
            new Notification("OVERDUE", message)
        );
    }
}

前端订阅通知:

// 逾期提醒订阅
const socket = new SockJS('/ws')
const stompClient = Stomp.over(socket)

stompClient.connect({}, () => {
  stompClient.subscribe(`/topic/user/${userId}`, (message) => {
    const notification = JSON.parse(message.body)
    if (notification.type === 'OVERDUE') {
      showOverdueAlert(notification.content)
    }
  })
})

5. 部署与性能优化

5.1 容器化部署方案

使用Docker Compose编排服务:

version: '3.8'

services:
  backend:
    build: ./backend
    ports:
      - "8080:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=prod
      - DB_URL=jdbc:mysql://db:3306/library
    depends_on:
      - db
      - redis

  frontend:
    build: ./frontend
    ports:
      - "80:80"
    depends_on:
      - backend

  db:
    image: mysql:8.0
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_DATABASE=library
    volumes:
      - db_data:/var/lib/mysql

  redis:
    image: redis:alpine
    ports:
      - "6379:6379"

volumes:
  db_data:

5.2 性能优化策略

后端优化:

  • 启用Spring Boot Actuator监控端点
  • 配置HikariCP连接池参数
  • 添加二级缓存(Redis)
  • 启用GZIP压缩响应

前端优化:

  • 路由懒加载
  • 组件异步加载
  • 静态资源CDN加速
  • 启用HTTP/2协议
# 示例:HikariCP配置
spring:
  datasource:
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5
      idle-timeout: 30000
      max-lifetime: 1800000
      connection-timeout: 30000

5.3 日志与监控

集成Prometheus和Grafana监控:

// 监控配置
@Configuration
public class MetricsConfig {
    
    @Bean
    MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() {
        return registry -> registry.config().commonTags(
            "application", "library-system"
        );
    }
    
    @Bean
    public TimedAspect timedAspect(MeterRegistry registry) {
        return new TimedAspect(registry);
    }
}

前端性能监控:

// 前端性能指标收集
const metrics = {
  FCP: 0,
  LCP: 0,
  FID: 0,
  CLS: 0
}

const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (entry.name === 'first-contentful-paint') {
      metrics.FCP = entry.startTime
    } else if (entry.name === 'largest-contentful-paint') {
      metrics.LCP = entry.startTime
    }
  }
})

observer.observe({ type: 'paint', buffered: true })
格拉姆角场(GAF)实战:用Python实现时间序列图像化处理 本文深入解析了格拉姆角场(GAF)技术,这是一种将一维时间序列转化为二维图像特征的方法,以便利用卷积神经网络(CNN)等图像模型进行深度分析。文章通过Python实战代码,详细演示了GASF和GADF两种核心转换的实现过程,并探讨了其在时序数据分类任务中的应用,为故障预警、金融模式识别等场景提供了强大的图像驱动分析视角。 阅读详情

相关推荐

zabbix添加IBM服务器SNMPV3监控

本地采用欧冠的是zabbix5.0,服务器型号是SR860,使用snmpv3因为只支持这个,醉了。说明:本地采用欧冠的是zabbix5.0,服务器型号是SR860。

萌新包大人的博客 1984

南工ACM:喷水装置1

描述 现有一块草坪,长为20米,宽为2米,要在横中心线上放置半径为Ri的喷水装置,每个喷水装置的效果都会让以它为中心的半径为实数Ri(0#include<stdio.h> #include<math.h> #define LEN 20 #define WID 2 void allocate(double* a,int n); void kuaipai(double* a,int l,in

丁磊_ml的博客 543

嵌入式常见英文2500词总结

嵌入式常见英文总结

qq_28576837的博客 1万+

喷水装置

标题现有一块草坪,长为20米,宽为2米,要在横中心线上放置半径为Ri的喷水装置,每个喷水装置的效果都会让以它为中心的半径为实数Ri(0<Ri<15)的圆被湿润,这有充足的喷水装置i(1<i<600)个,并且一定能把草坪全部湿润,你要做的是:选择尽量少的喷水装置,把整个草坪的全部湿润。 输入描述: 第一行m表示有m组测试数据 每一组测试数据的第一行有一个整数数n,n表示共有n...

沐目的博客 396

存储硬盘格式怎么把512还原为520格式??

硬盘厂商工具(如SeaChestsg_format)可以调整扇区大小。备份数据,因为调整扇区会清除硬盘内容。根据硬盘型号和接口类型,选择合适的工具进行调整。如果你需要更详细的帮助,请提供你的硬盘型号和存储设备类型。希望如上措施及解决方案能够帮到有需要的你。PS:如若遇到采纳如下方案还是未解决的同学,希望不要抱怨&&急躁,毕竟影响因素众多,我写出来也是希望能够尽最大努力帮助到同类似问题的小伙伴,即把你未解决或者产生新Bug黏贴在评论区,我们大家一起来努力,一起帮你看看,可以不咯。

**My Coding Family** 1146

把云端打印带回办公室:通信场景 SAP_COM_0466 打通 SAP BTP ABAP environment 与本地打印机的 Pull Integration 实战

摘要: 本文探讨云端SAP系统如何通过SAP_COM_0466通信场景实现与本地打印机的安全连接。核心方案采用Pull Integration模式,由本地组件(如SAP Cloud Print Manager或第三方OMS)主动从云端打印队列拉取任务,避免网络边界冲突。配置流程涵盖通信安排创建、打印队列绑定及权限管理,并强调队列类型必须选择"Pull Integration Queue"的关键细节。方案通过分离云端生产与本地打印环节,既保障安全性又便于运维监控,适用于SAP BTP AB

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 144

acm-喷水装置(一)

喷水装置(一) 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 现有一块草坪,长为20米,宽为2米,要在横中心线上放置半径为Ri的喷水装置,每个喷水装置的效果都会让以它为中心的半径为实数Ri(0 输入 第一行m表示有m组测试数据 每一组测试数据的第一行有一个整数数n,n表示共有n个喷水装置,随后的一行,有n个实数ri,ri表示该喷水装

zzyy17的专栏 625

华为自研 ERP、Oracle EBS 与 SAP 上线时系统配置思路设计差异深度分析

本文对比分析了华为自研ERP、Oracle EBS和SAP S/4HANA三大ERP系统在上线配置思路上的核心差异。从架构设计看,华为采用分布式微服务架构,SAP采用分层服务架构,Oracle采用集中式一体化架构;在模块配置上,华为以业务场景为导向,SAP基于行业模板,Oracle强调模块独立性;数据迁移方面,华为侧重业务规则清洗,SAP注重数据质量监控,Oracle依赖标准化工具;流程适配上,华为系统随流程调整,SAP在框架内优化,Oracle需定制开发;定制开发模式差异明显,华为采用插件化扩展,SAP使

金牌架构师 1454

喷水装置(一)

这道题目是水题,刷刷水题,练习c++ 喷水装置(一) 时间限制:3000ms | 内存限制:65535KB 难度:3 描述现有一块草坪,长为20米,宽为2米,要在横中心线上放置半径为Ri的喷水装置,每个喷水装置的效果都会让以它为中心的半径为实数Ri(0<Ri<15)的圆被湿润,这有充足的喷水装置i(1<i<600)个,并且一定能把草坪全部湿润,...

weixin_34309435的博客 644

Android蓝牙中的Rfcomm协议介绍

RFCOMM(Radio Frequency Communications)是一种基于蓝牙技术的串口仿真协议,以下是详细介绍:一、协议概述二、工作原理三、应用场景

手机-手表蓝牙开发工程师的博客 713

【20】方案管理器

方案管理器是Excel中一个非常强大且灵活的工具,适合用于多情景分析和比较。在复杂的决策过程中,它可以帮助用户快速管理和评估不同变量组合下的结果,从而优化决策过程。

学习,输出==》再学习再输出 1585

Spring Boot + Vue3 实现图书馆管理系统图书信息录入全流程

数据录入是信息管理系统的核心基础,其健壮性直接关系到后续所有业务流程的稳定。从技术原理上看,一个完整的数据录入流程涉及前端表单交互、后端接口校验、数据库事务控制等多个层面。在工程实践中,开发者需要关注数据校验、批量处理、异常回滚等关键细节,以确保数据的准确性和一致性。以图书馆管理系统为例,图书信息录入不仅是简单的增删改查,更是一个涵盖单条录入、批量导入、数据校验与日志记录的综合性工程任务。本文基于Spring Boot和Vue3技术栈,深入探讨如何构建一个企业级的图书信息录入解决方案,其中涉及到的**数据校

weixin_34194087的博客 333

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

图书管理系统 Java 17 + Spring Boot 3 架构设计:5大核心模块与3层架构实战解析

本文详细解析了基于Java 17和Spring Boot 3的图书管理系统架构设计,涵盖5大核心模块与3层架构实战。通过模块化设计和现代化技术栈,如Spring Data JPA、Lombok等,实现高效开发与可扩展性,为开发者提供完整的项目总体设计方案和技术实现细节。

470

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

计算机毕业设计springboot图书馆管理系统 基于Spring Boot架构的图书借阅与信息管理平台 智慧图书室数字化服务系统的设计与实现

在信息技术高速发展的当下,传统图书馆的人工管理模式已难以满足海量图书资源与读者需求的精准匹配。纸质登记、人工盘点、线下借阅等操作不仅效率低下,还容易出现信息错漏、资源闲置等问题。随着数字化转型的深入推进,构建一套高效、稳定、易用的图书管理信息化平台成为提升服务质量的必然选择。 本平台采用Spring Boot作为核心开发框架,结合MySQL数据库与B/S架构模式,实现了前后端分离的现代化系统设计。前端采用VUE技术构建交互界面,后端通过分层架构(表现层、业务逻辑层、数据访问层)确保系统的可维护性与扩展性。系

毕业设计-小章学姐 723

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

【计算机毕业设计】基于Springboot的图书馆座位预约系统

本文设计了一款基于Java、SpringBoot、MySQL与Vue技术的轻量化图书馆座位预约系统。系统采用前后端分离架构,包含用户端和管理员端两大模块:用户端提供注册登录、座位预约、签到签退、报修提交等功能;管理员端实现数据概览、公告管理、用户及预约管控等全维度管理。通过用例图展示功能权限,E-R图规范数据库设计,有效解决了传统图书馆人工管理效率低下、占座乱象等问题。系统兼顾易用性与管理效率,实现了座位资源的智能化调配,提升了高校图书馆的服务与管理水平。

xiaotianyuanma的博客 236

南阳理工ACM:喷水装置(一)题目及解法

描述 现有一块草坪,长为20米,宽为2米,要在横中心线上放置半径为Ri的喷水装置,每个喷水装置的效果都会让以它为中心的半径为实数Ri(0&lt;Ri&lt;15)的圆被湿润,这有充足的喷水装置i(1&lt;i&lt;600)个,并且一定能把草坪全部湿润,你要做的是:选择尽量少的喷水装置,把整个草坪的全部湿润。 输入 第一行m表示有m组测试数据 每一组测试数据的第一行有一个整数数n,n表示共有...

MISTLETOE_WW的博客 538

贪心算法--草坪浇灌 C++

现有一块草坪,长为20米,宽为2米,要在横中心线上放置半径为Ri的喷水装置,每个喷水装置的效果都会让以它为中心的半径为实数Ri(0&lt;Ri&lt;15)的圆被湿润,这有充足的喷水装置i(1&lt;i&lt;600)个,并且一定能把草坪全部湿润,你要做的是:选择尽量少的喷水装置,把整个草坪的全部湿润。【输入】第一行m表示有m组测试数据每一组测试数据的第一行有一个整数数n,n表示共有n个喷水装置,...

wangzhenxing991026的博客 1628

喷水装置(一)南阳oj

喷水装置(一) 描述 现有一块草坪,长为20米,宽为2米,要在横中心线上放置半径为Ri的喷水装置,每个喷水装置的效果都会让以它为中心的半径为实数Ri(0&lt;Ri&lt;15)0&lt;Ri&lt;15)01&lt;i&lt;600)1&lt;i&lt;600)1...

厄尔尼诺的博客 254

喷水装置(二)

题目描述 有一块草坪,横向长w,纵向长为h,在它的橫向中心线上不同位置处装有n(n&lt;=10000)个点状的喷水装置,每个喷水装置i喷水的效果是让以它为中心半径为Ri的圆都被润湿。请在给出的喷水装置中选择尽量少的喷水装置,把整个草坪全部润湿。 输入 第一行输入一个正整数N表示共有n次测试数据。 每一组测试数据的第一行有三个整数n,w,h,n表示共有n个喷水装置,w表示草坪的横向长度,h表...

一个和代码打交道の小孩 595

nyoj 12 喷水装置(二) 贪心 区间覆盖

思路很简单 根据坐标和半径 得到每个喷水设置能够覆盖的左右坐标  然后按左坐标从小到大排序  筛选时候如果喷水设置的左坐标小于等于起始点star用while循环寻找能够覆盖最大的右坐标 然后更新起始点star为寻找到的最大右坐标 具体看代码: #include #include #include using namespace std; struct node { double

苏苏爱自由 2785

NYOJ-6-喷水装置(一)

喷水装置(一) 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 现有一块草坪,长为20米,宽为2米,要在横中心线上放置半径为Ri的喷水装置,每个喷水装置的效果都会让以它为中心的半径为实数Ri(0<Ri<15)的圆被湿润,这有充足的喷水装置i(1<i<600)个,并且一定能把草坪全部湿润,你要做的是:选择尽量少的喷水装置,把整个草坪的全部湿润。 输入

x_y_q_的博客 2000
上一篇: 锂离子电池组平衡技术与BQ25887充电管理实践
下一篇: U-Boot 网络与存储命令实战:TFTP/NFS 加载内核与 EMMC 分区烧写 3 种方法
com_xpp
博客等级 码龄16年 23粉丝 160原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值