Spring Boot 3.2 + SQL Server 图书馆系统实战

发布时间:2026/9/18 0:41:11

Spring Boot 3.2 + SQL Server 图书馆系统实战 简介本资源是一份面向计算机专业本科生的Java毕业设计实战资料聚焦图书馆管理系统的完整开发流程适用于课程设计、毕设选题与Java Web项目学习。文档以Word格式呈现共1个917KB的.doc文件内容覆盖绪论、需求分析含可行性论证、用例图与类图、系统设计数据库表结构、管理员与读者权限划分、Java实现细节模块化功能代码逻辑及多层级测试方案单元测试与集成测试目录结构完整含摘要、中英文目录、六章正文及未来展望。已有115人下载学习读者可直接获取规范的学术论文框架、可复用的系统架构设计思路、基于Java的前后端协同实现要点以及从需求建模到测试验证的全流程实践参考特别适合夯实Java基础、理解MVC开发模式并完成高质量毕业课题的学生。1. 这不是又一个“增删改查”Demo基于Java的图书馆管理系统毕业设计本质是用Spring BootSQL Server落地真实业务闭环很多同学拿到“基于Java的图书馆管理系统”这个毕设题目时第一反应是套用教科书式三层架构、写几个Servlet跳转页面、连个H2内存库跑通CRUD就交差。但现实中的图书馆系统远不止借还书——它要处理超期罚款的阶梯计算、多角色并发预约冲突检测、馆藏状态实时同步在架/借出/编目中/丢失、ISBN校验与元数据自动补全还要应对期末高峰期单日3000借阅请求的事务一致性。本设计之所以被评优关键在于它没把SQL Server当“玩具数据库”用启用行级锁控制并发预约、用存储过程封装借阅规则引擎、通过SQL Server Agent定时归档历史操作日志、利用全文索引加速题名模糊检索。适合计算机/信管专业学生复现——你不需要部署Oracle或MySQL集群只要装好SQL Server 2019含SSMS和JDK 17就能跑通从管理员排班、读者扫码借书到馆长生成借阅热力图的完整链路。文中所有代码、SQL脚本、配置参数均来自实际可运行的源码包非教学简化版。2. 用Spring Boot 3.2 MyBatis-Plus在本地跑通图书馆系统的最小命令2.1 为什么选Spring Boot而非传统SSM——毕业设计必须规避的三个技术债陷阱毕业设计最常踩的坑是用Struts2Hibernate这种已淘汰组合强行“复古”。而本系统选择Spring Boot 3.2非2.x核心理由有三第一自动装配SQL Server驱动。传统SSM需手动配置sqljdbc42.jar路径、写冗长的DriverManagerDataSourceBean而Spring Boot 3.2内置spring-boot-starter-data-jdbc只需在application.yml中声明spring.datasource.urljdbc:sqlserver://localhost:1433;databaseNameLibDB;encryptfalse;trustServerCertificatetrue启动时自动加载mssql-jdbc12.6.0.jre11驱动第二MyBatis-Plus的LambdaQueryWrapper规避SQL注入风险。比如读者查询借阅记录传统写法SELECT * FROM borrow_record WHERE reader_id readerId极易被构造readerId1 OR 11攻击而lambdaQuery().eq(BorrowRecord::getReaderId, readerId).list()由框架生成预编译SQL第三Actuator端点直出生产级监控。毕设答辩时老师常问“怎么保证高并发下借书不超量”直接打开http://localhost:8080/actuator/metrics/jvm.memory.used看堆内存比口头解释更有力。提示务必使用JDK 17非8或11。Spring Boot 3.x要求JDK 17若用JDK 8编译会报java.lang.UnsupportedClassVersionError。验证命令java -version输出应为17.0.x。2.2 创建项目骨架的5条命令含SQL Server连接验证# 1. 使用Spring Initializr生成基础工程关键依赖 curl -X POST https://start.spring.io/starter.zip \ -H Content-Type: application/json \ -d { groupId: com.libsys, artifactId: libsys-backend, name: Library Management System, description: Gradle-based Spring Boot 3.2 project for library system, packageName: com.libsys, packaging: jar, javaVersion: 17, dependencies: [ {id:spring-boot-starter-web}, {id:spring-boot-starter-jdbc}, {id:mybatis-plus-spring-boot3-starter}, {id:spring-boot-starter-validation}, {id:spring-boot-starter-thymeleaf}, {id:spring-boot-starter-actuator} ] } --output libsys.zip # 2. 解压并进入目录 unzip libsys.zip cd libsys-backend # 3. 添加SQL Server专用依赖pom.xml中dependencies内追加 # 注意必须用mssql-jdbc 12.6.0.jre11低版本不支持TLS 1.2加密 dependency groupIdcom.microsoft.sqlserver/groupId artifactIdmssql-jdbc/artifactId scoperuntime/scope /dependency # 4. 配置application.ymlsrc/main/resources/下 spring: datasource: url: jdbc:sqlserver://localhost:1433;databaseNameLibDB;encryptfalse;trustServerCertificatetrue username: sa password: YourStrongPass123 # SQL Server sa密码非Windows登录密码 driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver sql: init: mode: always schema-locations: classpath:schema.sql >// src/main/java/com/libsys/generator/CodeGenerator.java public class CodeGenerator { public static void main(String[] args) { AutoGenerator generator new AutoGenerator(); // 1. 数据源配置指向你的SQL Server DataSourceConfig dataSourceConfig new DataSourceConfig() .setUrl(jdbc:sqlserver://localhost:1433;databaseNameLibDB) .setUsername(sa) .setPassword(YourStrongPass123) .setDriverName(com.microsoft.sqlserver.jdbc.SQLServerDriver); generator.setDataSource(dataSourceConfig); // 2. 全局配置指定输出路径 GlobalConfig globalConfig new GlobalConfig() .setOutputDir(System.getProperty(user.dir) /src/main/java) .setAuthor(student) .setOpen(false); // 不自动打开生成的文件夹 generator.setGlobalConfig(globalConfig); // 3. 包配置按模块分包 PackageConfig packageConfig new PackageConfig() .setParent(com.libsys) .setEntity(entity) .setMapper(mapper) .setService(service) .setController(controller); generator.setPackageInfo(packageConfig); // 4. 策略配置关键指定表名SQL Server需用方括号包裹 StrategyConfig strategyConfig new StrategyConfig() .addInclude([book], [reader], [borrow_record]) // 必须加[]否则识别失败 .setNaming(NamingStrategy.underline_to_camel) // 下划线转驼峰 .setColumnNaming(NamingStrategy.underline_to_camel) .setEntityLombokModel(true); // 生成Data注解 generator.setStrategy(strategyConfig); generator.execute(); } }运行该main方法后在src/main/java/com/libsys/entity/Book.java中会生成Data TableName(book) // 显式标注表名因SQL Server表名含特殊字符 public class Book { TableId(type IdType.INPUT) // ISBN为主键需手动输入 private String isbn; private String title; private String author; private LocalDate publishDate; // SQL Server DATE类型映射为LocalDate private Integer totalCopies; private Integer availableCopies; }注意SQL Server的CHAR(13)类型如ISBN在Java中必须用String接收不能用Long——否则9787302584210会被截断为978730258421末位0丢失。MyBatis-Plus默认映射正确但手写XML时需确认resultTypestring。3. SQL Server核心配置与图书馆业务逻辑的深度绑定3.1 用存储过程实现借阅规则引擎解决“同一本书最多借3本”的原子性问题图书馆业务中“读者A借第3本《算法导论》时系统必须检查其当前已借该书数量”。若用Java代码先SELECT COUNT(*)再INSERT高并发下会出现超借两个请求同时查到“已借2本”都执行插入。本设计用SQL Server存储过程解决-- src/main/resources/sql/borrow_book.sql CREATE PROCEDURE sp_borrow_book isbn CHAR(13), reader_id VARCHAR(10), borrow_date DATE, result INT OUTPUT -- 返回值1成功, 0超限, -1库存不足 AS BEGIN SET NOCOUNT ON; BEGIN TRY BEGIN TRANSACTION; -- 步骤1检查读者状态是否冻结 IF NOT EXISTS (SELECT 1 FROM reader WHERE reader_id reader_id AND status 1) BEGIN SET result -2; -- 读者状态异常 ROLLBACK; RETURN; END -- 步骤2检查该读者已借此书数量含未归还记录 DECLARE borrowed_count INT; SELECT borrowed_count COUNT(*) FROM borrow_record WHERE isbn isbn AND reader_id reader_id AND return_date IS NULL; IF borrowed_count 3 BEGIN SET result 0; -- 超过3本限制 ROLLBACK; RETURN; END -- 步骤3检查库存行级锁防止并发扣减 IF NOT EXISTS (SELECT 1 FROM book WITH (UPDLOCK, ROWLOCK) WHERE isbn isbn AND available_copies 0) BEGIN SET result -1; -- 库存不足 ROLLBACK; RETURN; END -- 步骤4执行借阅插入记录扣减库存 INSERT INTO borrow_record (isbn, reader_id, borrow_date) VALUES (isbn, reader_id, borrow_date); UPDATE book SET available_copies available_copies - 1 WHERE isbn isbn; SET result 1; -- 成功 COMMIT; END TRY BEGIN CATCH ROLLBACK; SET result -99; -- 未知错误 END CATCH ENDJava调用方式在BorrowService中Select(EXEC sp_borrow_book #{isbn}, #{readerId}, #{borrowDate}, #{result} OUTPUT) void borrowBook(Param(isbn) String isbn, Param(readerId) String readerId, Param(borrowDate) LocalDate borrowDate, Param(result) int[] result); // 调用后检查result[0]值判断结果提示WITH (UPDLOCK, ROWLOCK)是关键。它对匹配的book行加更新锁阻止其他事务读取该行直到本事务结束避免“检查库存”和“扣减库存”之间被其他请求插入。3.2 利用SQL Server全文索引加速题名模糊检索图书馆系统高频操作是“找书”用户输入“人工智能”期望匹配《人工智能导论》《机器学习实战》《深度学习》等。若用LIKE %人工智能%SQL Server无法使用普通索引全表扫描极慢。本设计启用全文索引-- 在SQL Server中执行需管理员权限 -- 1. 启用数据库全文索引 USE LibDB; EXEC sp_fulltext_database enable; -- 2. 为book表的title列创建全文索引 CREATE FULLTEXT CATALOG ft_catalog AS DEFAULT; CREATE FULLTEXT INDEX ON book(title) KEY INDEX PK__book__... -- 替换为book表实际主键索引名 ON ft_catalog; -- 3. 查询示例比LIKE快10倍以上 SELECT isbn, title, author FROM book WHERE CONTAINS(title, 人工智能 OR AI );Java中对应Mapper XML!-- BorrowMapper.xml -- select idsearchBooksByKeyword resultTypeBook SELECT isbn, title, author FROM book WHERE CONTAINS(title, #{keyword}) /select3.3 用SQL Server Agent实现借阅超期自动提醒毕业设计常忽略“系统如何主动通知读者”本设计用SQL Server Agent定时任务非Java线程池确保可靠性-- 创建提醒存储过程 CREATE PROCEDURE sp_send_overdue_reminder AS BEGIN -- 查找超期未还记录超30天 SELECT r.reader_id, r.name, r.phone, b.title, br.borrow_date INTO #overdue_list FROM borrow_record br JOIN reader r ON br.reader_id r.reader_id JOIN book b ON br.isbn b.isbn WHERE br.return_date IS NULL AND DATEDIFF(day, br.borrow_date, GETDATE()) 30; -- 实际发送短信/邮件逻辑在此处演示用PRINT DECLARE msg NVARCHAR(200); DECLARE overdue_cursor CURSOR FOR SELECT 读者 name 您借阅的《 title 》已超期 FROM #overdue_list; OPEN overdue_cursor; FETCH NEXT FROM overdue_cursor INTO msg; WHILE FETCH_STATUS 0 BEGIN PRINT msg; -- 真实环境替换为调用短信API FETCH NEXT FROM overdue_cursor INTO msg; END CLOSE overdue_cursor; DEALLOCATE overdue_cursor; END在SQL Server Management Studio中展开“SQL Server Agent” → “作业” → 右键“新建作业”常规页名称Daily Overdue Reminder步骤页新建步骤类型Transact-SQL 脚本(TSQL)命令EXEC sp_send_overdue_reminder调度页设置每天上午9点执行注意SQL Server Express版不支持Agent需用Standard或Developer版。学生可下载免费的SQL Server 2019 Developer Edition。4. 毕业设计答辩必答的3个技术细节与参数调优清单4.1 HikariCP连接池关键参数调优针对SQL Server特性HikariCP是Spring Boot默认连接池但未针对SQL Server优化。以下参数在application.yml中调整spring: datasource: hikari: connection-timeout: 30000 # 连接超时30秒SQL Server默认登录超时15秒需略长 maximum-pool-size: 20 # 最大连接数CPU核数×(4~5)4核机器设20足够 minimum-idle: 5 # 最小空闲连接避免频繁创建销毁 idle-timeout: 600000 # 空闲连接存活600秒10分钟 max-lifetime: 1800000 # 连接最大生命周期30分钟SQL Server默认连接池超时1小时 connection-test-query: SELECT 1 # SQL Server用SELECT 1测试连接有效性 leak-detection-threshold: 60000 # 连接泄漏检测阈值60秒防止Connection未close验证连接池状态访问http://localhost:8080/actuator/metrics/hikaricp.connections.active正常值应在0~20间波动若长期为20说明有连接未关闭——检查BorrowService中是否漏写try-with-resources。4.2 SQL Server日期类型与Java LocalDateTime的兼容方案SQL Server的DATETIME类型精度为3.33毫秒而JavaLocalDateTime无时区信息。若直接映射会导致2023-10-01 14:30:00.123存入后读出为2023-10-01 14:30:00.120毫秒舍入。解决方案// 自定义TypeHandlersrc/main/java/com/libsys/handler/SqlServerDateTimeHandler.java MappedTypes(LocalDateTime.class) MappedJdbcTypes(JdbcType.DATE) public class SqlServerDateTimeHandler implements TypeHandlerLocalDateTime { Override public void setParameter(PreparedStatement ps, int i, LocalDateTime parameter, JdbcType jdbcType) throws SQLException { if (parameter null) { ps.setNull(i, Types.DATE); } else { // 转为SQL Server兼容的字符串格式 ps.setString(i, parameter.format(DateTimeFormatter.ofPattern(yyyy-MM-dd HH:mm:ss.SSS))); } } Override public LocalDateTime getResult(ResultSet rs, String columnName) throws SQLException { String value rs.getString(columnName); return value null ? null : LocalDateTime.parse(value, DateTimeFormatter.ofPattern(yyyy-MM-dd HH:mm:ss.SSS)); } }在BookMapper.xml中引用resultMap idBookResultMap typeBook result propertypublishDate columnpublish_date typeHandlercom.libsys.handler.SqlServerDateTimeHandler/ /resultMap4.3 毕业设计答辩高频问题应答模板问题应答要点用技术事实支撑关联代码位置“为什么用SQL Server而不是MySQL”“SQL Server的行级锁ROWLOCK和存储过程对借阅并发控制更精准全文索引对中文题名检索性能优于MySQL 5.7的FULLTEXT且学校机房统一部署SQL Server符合实际运维环境。”sp_borrow_book.sql,schema.sql中全文索引语句“如何保证借书事务的ACID”“借阅操作封装在存储过程中用BEGIN TRANSACTIONTRY/CATCH确保原子性库存扣减前加UPDLOCK锁防止超借日志表borrow_record有唯一约束(isbn,reader_id,return_date IS NULL)防重复借阅。”sp_borrow_book.sql中事务块borrow_record表结构“系统如何应对期末借阅高峰”“连接池最大20连接HikariCP连接复用借阅操作用存储过程减少网络往返热点数据如热门图书在Java层加Caffeine缓存TTL10分钟。”application.yml连接池配置BookService.java中Cacheable注解5. 用Navicat连接SQL Server并导出可答辩的ER图与流程图5.1 Navicat连接SQL Server的6步实操避坑指南Navicat是毕业设计画ER图最常用工具但连接SQL Server易失败。正确步骤下载Navicat Premium 16免费试用14天够答辩用新建连接→ 选择“Microsoft SQL Server” → 填写连接名LibDB_Local主机名/IP地址127.0.0.1不能填localhostNavicat解析localhost可能走IPv6端口1433SQL Server默认端口数据库LibDB必须提前在SSMS中创建好用户名sa密码YourStrongPass123同application.yml中密码高级选项卡→ 勾选“允许空密码”若sa密码为空则勾选SSL选项卡→ 加密方式选“不使用SSL”避免证书错误测试连接→ 点击“连接测试”成功后保存双击连接→ 展开LibDB→ 右键“查询” → 新建查询 → 执行SELECT TOP 10 * FROM book验证数据提示若报错Cannot connect to database server检查SQL Server配置管理器中“SQL Server (MSSQLSERVER)”服务是否启动且“TCP/IP协议”已启用右键TCP/IP→启用。5.2 从Navicat自动生成ER图并导出答辩PPT连接成功后右键LibDB→ “反向数据库到模型”勾选book、reader、borrow_record三张表 → 下一步在ER图界面选中关系线 → 右键“编辑关系” → 设置borrow_record.reader_id→reader.reader_id一对多一个读者可借多本书borrow_record.isbn→book.isbn多对一一本书可被多人借调整布局拖动表使关系线不交叉 → 顶部菜单“文件” → “导出为” → “PNG图像”将PNG插入答辩PPT在图旁标注borrow_record表中return_date为NULL表示未归还book.available_copies由存储过程自动维护Java层只读5.3 图书馆系统核心流程图绘制规范答辩加分项流程图不是画得越复杂越好而是体现业务闭环。用draw.io免费在线工具绘制重点突出三个节点graph TD A[读者扫码借书] -- B{调用sp_borrow_book} B -- C[检查读者状态] C -- D[检查已借数量] D -- E[检查库存] E -- F[插入borrow_record] F -- G[更新book.available_copies] G -- H[返回借阅成功] C -.- I[状态冻结] -- J[拒绝借阅] D -.- K[已借3本] -- J E -.- L[库存为0] -- J在答辩PPT中将此图与sp_borrow_book.sql代码并列展示并强调“所有业务规则在数据库层强制执行Java层只做参数校验和结果处理降低系统耦合度。”最后检查src/main/resources/static/目录下是否有index.htmlThymeleaf模板启动后访问http://localhost:8080能看到管理员登录页——这意味着整个系统已具备可演示的最小闭环答辩时打开浏览器现场操作借还书比讲一百页PPT更有说服力。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/9/18 0:41:11

Ubuntu移动硬盘安装指南:打造随身便携Linux系统

1. 为什么要把 Ubuntu 装进移动硬盘:一个随身系统的实用价值先聊聊我折腾这件事的初衷。前几年我一直在一台 Windows 台式机和一台笔记本之间切换工作,环境不统一是很头疼的事:台式机上配好的 Python 环境、Docker 容器、编译工具链&#xff…

2026/9/18 0:36:11

Unity RPG开发实战:FSM与行为树在角色AI中的工程落地

简介:本资源是一份面向计算机专业本科生及Unity初学者的RPG游戏开发毕业论文,聚焦于使用Unity3D引擎完成一款具备完整叙事与交互机制的三维角色扮演游戏的设计与实现。论文系统梳理了RPG发展脉络、Unity3D跨平台开发优势,并深入展开文案设计&…

2026/9/18 0:36:11

Chat 反复弹 401?Trae 的 Base URL 走 TaoToken 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/18 2:41:16

力扣31题下一个排列:字典序算法与双指针三步详解

刷题这事,我一直有个观点:真正值得反复琢磨的,往往不是那些难到劝退的压轴题,而是看起来“中等偏易”、背后却藏着完整套路模板的题。力扣第31题“下一个排列”就是其中最典型的一道,它同时出现在热题100和不少大厂笔试…

2026/9/18 2:41:16

Gyroflow 视频防抖:从安装、调参到导出稳画面的完整教程

Gyroflow 视频防抖:从安装、调参到导出稳画面的完整教程 【免费下载链接】gyroflow Video stabilization using gyroscope data 项目地址: https://gitcode.com/GitHub_Trending/gy/gyroflow Gyroflow 是一款基于陀螺仪数据的开源视频防抖工具,它…

2026/9/18 2:41:16

ATmega328+TB67S531FTG工业步进电机控制方案

1. 项目概述:为什么工业现场还在用ATmega328驱动步进电机?在工业自动化和机器人开发一线干了十多年,我见过太多人一上来就堆ROS2、树莓派CM0 Nano、甚至直接上工业级AI视觉套件,结果连最基础的执行器——两相双极步进电机——都抖…

2026/9/18 2:41:16

Windows命令行字符处理实战:从findstr到for/f与PowerShell

做Windows运维和日常办公自动化,有一件事绕不开:在命令行里处理字符串。格式不对的日志、几百个文件里的统一替换、临时想从一个1GB的文件里捞几行关键信息——这些活如果靠鼠标在GUI里一层层点,十有八九会把时间耗在重复劳动上,而…

2026/9/18 2:36:16

人才测评题库结构化:从Word文档到可验证JSON题库

简介:本资源是一份面向HR从业者、企业招聘专员、职业测评师及自我提升学习者的人际交往能力专项测评题库,聚焦人才选拔与软技能评估场景。内含两套结构化笔试题:第一套15题侧重人际交往倾向与社交习惯自评,第二套12题考察人际问题…

2026/9/16 12:52:37

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/18 0:01:09

Google Colab 实战:运行模型、数据加载与报错排查

1. 为什么我劝你先搞懂 Colab 的运行模型1.1 Colab 到底是什么,跟本地跑代码差在哪Google Colab 简单说就是一台跑在浏览器里的 Linux 虚拟机,你打开一个 Notebook,背后就连上了一台带 GPU 的远程机器。你在单元格里敲的每一行 Python&#x…

2026/9/18 0:01:09

C语言数据类型与表达式详解

1. C语言数据与数据类型概述在C语言编程中,数据是程序处理的核心对象。理解数据的分类和特性是掌握C语言的基础。C语言中的数据主要分为四大类:常量、变量、表达式和函数。这些数据类型构成了C语言程序的基本元素,每种类型都有其独特的特性和…

2026/9/18 0:01:09

SQL时间字段指定时间段查询:区间语义、索引与时区避坑

上周排查一个线上问题&#xff0c;用户反馈"昨天的订单一条都没查到"&#xff0c;但数据库里明明躺着两千多条。最后定位下来&#xff0c;不是数据丢了&#xff0c;也不是接口挂了&#xff0c;而是那个查询条件把时间段写成了> 2024-05-20 00:00:00 AND < 2024…

2026/9/16 22:55:57

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行&#xff0c;Type-C接口算是典型的“看着简单&#xff0c;做起来全坑”的东西。光引脚就24个&#xff0c;高低速信号、电源、控制线全部塞在一个小小的连接器里&#xff0c;如果PCB布局不做规划&#xff0c;打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/16 22:56:09

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/16 22:56:16

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码