新闻详情

新闻详情

首页 / 资讯中心 / 详情

SpringBoot电竞赛事管理系统实战:表结构、JWT鉴权与赛程排名实现

发布时间:2026/9/28 12:09:10来源:尧图网络
SpringBoot电竞赛事管理系统实战:表结构、JWT鉴权与赛程排名实现
开头每年到了四五月份一堆同学就开始在群里问“SpringBoot做个什么系统比较好”“有没有现成的电竞赛事管理系统参考一下”。说实话如果你对电竞、赛事数据、赛程编排这些有兴趣又需要一个能体现基本功的Java Web项目基于SpringBoot的电竞赛事管理系统是个相当合适的选题。它不像电商系统那么千篇一律也不用堆太多中间件但该有的CRUD、分页、鉴权、状态流转、数据统计全都有正好覆盖课程设计和毕业设计的核心考察点。这篇文章就从这个项目本身出发按“整体设计—技术选型—数据库设计—后端实现—前端对接—问题排查”这条线完整拆一遍。我会把每个模块为什么这么设计、表结构怎么建、关键代码怎么写、哪些坑我实际踩过都讲清楚。不论你手里已经有一份源码准备二次开发还是打算从零自己撸一个交作业这篇希望都能帮你把思路理顺少走弯路。1. 项目定位与整体架构设计1.1 核心需求解析赛事系统到底要管什么很多同学拿到这类题目第一反应是“不就是几个增删改查吗”做出来交上去才发现评分老师问一句“赛程冲突怎么处理”“积分排名怎么算”就直接卡住。所以先别急着写代码把需求拆明白。一个电竞赛事管理系统围绕的核心对象是“赛事Event/Match”但又不止于赛事本身至少得覆盖这样几条业务线赛事基础信息管理赛事名称、举办时间、地点线上/线下、项目类型LOL、CS2、DOTA2、王者荣耀等、参赛规模、赛制说明、赛事状态未开始/报名中/进行中/已结束。战队与选手管理报名队伍列表、战队成员名单、替补信息、所属赛区。赛程与对阵管理小组赛/淘汰赛的单场对阵比赛时间、场地/房间号、胜负结果、比分。积分与排名循环赛制下需要算积分胜场、净胜分淘汰赛需要记录晋级关系与最终名次。数据统计与展示参赛战队数、完赛率、战队胜率、场均击杀类数据展示这部分是加分项非常能体现数据库聚合查询的能力。再往大了说还可以扩展用户登录、比赛录像上传、赛事新闻公告、裁判员管理等功能但对课程设计/毕业设计而言把上面这五条做扎实答辩完全够用。1.2 分层架构与请求流转方式项目整体采用经典的三层架构Controller层接收前端请求Service层处理业务逻辑Mapper层持久层操作数据库。这个结构从SSH时代一直用到SpringBoot优点不是说它有多先进而是每层的职责非常清晰老师问起来你能一句话讲明白。请求流转大概是这样的前端页面Thymeleaf模板或Vue页面发起HTTP请求SpringBoot的Controller通过RestController接收请求并做参数校验随后调用Service接口的实现类Service层负责写具体业务规则比如赛程状态不允许撤回比分、淘汰赛对阵不能随意修改数据访问由Mapper接口配合MyBatis完成。在工程目录上我建议按功能分包而不是按技术类型分包比如controller、service、mapper、entity、vo、common这样结构更直观。很多同学喜欢搞com.xxx.controller、com.xxx.service这种没问题但注意类名一定要带模块前缀比如MatchController、EventController、TeamController不要全叫InfoController否则后面找代码能把自己找晕。1.3 为什么这种设计适合课程设计/毕业设计从答辩角度考虑分层架构最大的好处是“可讲的东西多”。老师问Controller层干嘛的你可以答参数接收与响应封装问Service层干嘛的你可以举赛程状态机的例子问Mapper层干嘛的你可以聊聊SQL优化和分页插件。每层都有真实业务在支撑而不是背概念。从工作量角度考虑这个项目规模适中后端大概二十来个接口数据库七八张表一个人在一到两周内做完是合理的。既不会像电商系统那样订单、支付、库存全上导致写不完也不会像“学生信息管理系统”那样只有单表CRUD显得太单薄。2. 技术选型与核心依赖解析2.1 框架版本不追求新稳定兼容才是王道这里要特别提醒一句SpringBoot版本不要盲目追新用社区最成熟的版本就行。根据目前大量课设/毕设项目的主流使用习惯SpringBoot 2.7.x搭配JDK 1.8是稳妥的选择。原因有两点网上教程、博客、已有的案例源码大多数基于SpringBoot 2.x遇到问题搜得到答案。MyBatis-Plus、Shiro、JWT等常用依赖对SpringBoot 2.x的兼容性已经非常稳定。SpringBoot 3.x必须用JDK 17而且部分第三方starter还没跟上项目启动报错会平白消耗大量时间。2.2 持久层框架MyBatis-Plus比原生MyBatis更省事持久层我强烈建议用MyBatis-Plus而不是纯MyBatis。它的BaseMapper接口直接封装了单表增删改查像赛事列表的分页查询、战队的条件筛选基本只需要写一个selectPage配合LambdaQueryWrapper就能完成不用手写一堆XML。举个例子按赛事状态和项目类型筛选赛事列表用MyBatis-Plus写起来是这样的PageEvent page new Page(current, size); LambdaQueryWrapperEvent wrapper new LambdaQueryWrapper(); wrapper.eq(StringUtils.hasText(status), Event::getStatus, status) .eq(StringUtils.hasText(gameType), Event::getGameType, gameType) .orderByDesc(Event::getStartTime); eventMapper.selectPage(page, wrapper);不需要写SQL条件动态拼接的问题也自动解决了。当然联表查询还是要写注解SQL或XML比如查“某个战队的所有比赛记录”就要关联赛事表和赛程表这部分MyBatis-Plus也支持自定义方法。2.3 认证方案JWT还是Session很多课程设计用的SpringSecurity或Shiro来做登录这对一个管理系统来说确实有点重。我的建议是如果只是给管理员和普通用户做登录区分直接用JWT加拦截器就够了实现难度低答辩时还能把Token认证流程讲清楚。JWT说白了就是一个包含用户信息和过期时间的加密字符串用户登录成功后后端签发Token返回给前端前端每次请求在Header里带上后端通过拦截器解析校验。无状态、不用存Session部署也方便。具体实现分三步登录接口校验用户名密码生成Token写一个JwtInterceptor拦截需要认证的请求注册拦截器时排除登录和注册路径。Token生成可以用io.jsonwebtoken:jjwt工具库代码量不大。2.4 核心依赖清单与配置要点pom.xml里的核心依赖大致是这些spring-boot-starter-webWeb基础能力内置Tomcat。mysql-connector-jMySQL驱动注意SpringBoot 2.7用的版本是8.0.33左右对应com.mysql.cj.jdbc.Driver。mybatis-plus-boot-starterMyBatis-Plus的启动器。lombok简化实体类代码Data注解一键生成getter/setter。jjwt或java-jwt生成和校验Token。spring-boot-starter-validation参数校验注解。application.yml里最容易被忽略的是时间配置和驼峰映射spring: datasource: url: jdbc:mysql://localhost:3306/esport?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: root jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: Asia/Shanghai mybatis-plus: configuration: map-underscore-to-camel-case: true global-config: db-config: logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 0map-underscore-to-camel-case这个配置非常关键它能把数据库字段start_time自动映射到实体类属性startTime否则你查出来的时间字段全部是null而且很难排查。逻辑删除配置也是建议在一开始就加上删除战队、删除赛程时用的是逻辑删除而不是物理删除保留数据痕迹对后面数据统计很有帮助。3. 数据库设计3.1 表结构总览七张表怎么划分数据库设计是这个项目的灵魂表建得好不好直接决定后面写代码时是行云流水还是各种join救火。基于上面拆解的需求建议设计七张核心表表名说明核心字段user用户表id, username, password, nickname, roleevent赛事表id, name, game_type, start_time, end_time, location, status, descriptionteam战队表id, name, game_type, region, coach, logo, contactplayer选手表id, team_id, name, position, game_role, statusmatch_info赛程/对阵表id, event_id, round_type, team_a_id, team_b_id, winner_id, status, start_timematch_result比分结果表id, match_id, team_id, score, is_winnerannouncement公告表可选id, title, content, create_time其中user表是独立体系announcement可有可无核心是前六张。match_info和match_result的设计可能和不少同学最初的直觉不一样这里重点解释一下。3.2 赛程与比分为什么拆成两张表很多初学着会把比分字段直接塞进match_info表里像score_a int、score_b int这样当时写起来简单可一旦要做“战队历史战绩”“单场比赛的每一小局比分”就会很别扭。拆成match_info和match_result之后match_result是明细表每一行记录的是“某场比赛里某支战队的总比分或单局比分”。这样设计有几个实际好处支持BO3、BO5多局赛制match_result里可以加game_index字段记录第几局。查询战队战绩时直接对match_result按team_id聚合不用拆字符串。比分修改只动结果表不影响对阵关系。另外match_info上还有一个容易忽略的设计细节需要冗余event_id。表面上看“比赛肯定属于某个赛事”但如果只通过联表去查后面写“某赛事所有比赛”的SQL会多一层查询。冗余一个外键字段查询简单很多这个属于典型的用空间换时间的做法。3.3 状态字段统一用枚举还是字符串我的建议是数据库里存字符串Java代码里用枚举做逻辑判断。比如赛事状态status字段在库里存0、1、2这样的数字确实省空间但是可读性太差导出数据看一眼全是数字还要去翻文档。存REGISTERING、RUNNING、FINISHED这种英文状态码既直观又符合SpringBoot项目的习惯。Java侧定义枚举public enum EventStatus { NOT_STARTED(0, 未开始), REGISTERING(1, 报名中), RUNNING(2, 进行中), FINISHED(3, 已结束); private final int code; private final String desc; // 构造方法、getter }前端需要显示时后端VO里直接带上statusDesc字段前端只显示描述文本避免前端做一堆if/else映射。3.4 几个容易踩坑的字段设计细节时间字段建议统一用datetime不要用timestamp。虽然timestamp支持时区转换看起来更智能但很多地区服务器和本地时间差八小时的问题都是它造成的干脆用datetime配合serverTimezoneAsia/Shanghai省心很多。删除标记字段deleted要设置默认值0逻辑删除只在Mapper层拦截写查询时MyBatis-Plus会自动追加deleted0条件不用手动处理但注意联表查询时如果自己写SQL要记得手动带上这个条件。唯一约束不要滥用像战队表的name字段如果设置了唯一约束后期想改队名就会被数据库挡住建议只在用户表username上设置唯一索引。战队换名字是很常见的运营操作别给自己找麻烦。4. 后端核心功能实现4.1 登录鉴权与JWT拦截器登录功能看似简单但涉及密码加密、Token签发、拦截器注册三个环节。密码存储建议用BCryptPasswordEncoder做哈希加密不要用MD5因为MD5存在彩虹表风险答辩时提一句BCrypt的加盐机制能加分不少。登录接口逻辑大概是这样的PostMapping(/login) public Result login(RequestBody LoginRequest req) { User user userService.lambdaQuery() .eq(User::getUsername, req.getUsername()) .one(); if (user null || !passwordEncoder.matches(req.getPassword(), user.getPassword())) { return Result.error(用户名或密码错误); } String token JwtUtil.generateToken(user.getId(), user.getUsername(), user.getRole()); return Result.success(Collections.singletonMap(token, token)); }注意passwordEncoder.matches()是校验方法对比的是“明文密码”和“数据库里的哈希值”不是重新加密后做equals这个概念很多同学会搞错。拦截器里校验Token后把用户信息放入ThreadLocal或RequestContext方便Service层获取当前操作者。比如记录“谁修改了这场比赛信息”时直接从上下文取用户身份即可。4.2 赛事管理模块CRUD背后的状态流转赛事模块的基本CRUD不复杂但有三个细节值得认真处理。第一个是关于赛事创建的参数校验。比如开始时间必须早于结束时间赛事状态为“报名中”时赛事名称不能重复。这些校验用spring-boot-starter-validation的Validated注解加NotNull、Future就能做不需要在Controller里写一堆if判断。第二个是状态流转的规则。赛事状态不能从“报名中”直接跳到“已结束”中间必须经过“进行中”。最简单的方式是在Service层写一个状态流转的方法public void changeEventStatus(Long eventId, EventStatus targetStatus) { Event event getById(eventId); // 校验当前状态是否允许流转到目标状态 if (!event.getStatus().canTransferTo(targetStatus)) { throw new BusinessException(非法状态流转); } event.setStatus(targetStatus.getCode()); updateById(event); }状态流转规则写在枚举类里用EnumSet或Map维护允许的转移关系。这样写的好处是规则集中管理后面要加状态也很方便。第三个是列表分页查询的VO封装。数据库实体Entity和前端展示对象VO一定要分开实体类里的字段直接映射数据库VO可以根据页面需要增删字段。比如赛事列表页除了赛事信息还想显示当前已报名战队数就需要在VO里加一个teamCount字段由Service层通过聚合查询填充。4.3 赛程管理状态机与比分录入的设计思路赛程表match_info的状态建议设计成NOT_STARTED未开始、LIVE进行中、FINISHED已结束。这个状态由后台操作触发流转和赛事整体状态是两个层面不要搞混。创建对阵时的核心校验是时间冲突。同一战队的两个比赛不能挤在同一时间段这个可以用一条SQL查出来LambdaQueryWrapperMatchInfo wrapper new LambdaQueryWrapper(); wrapper.eq(MatchInfo::getStatus, NOT_STARTED) .and(w - w.eq(MatchInfo::getTeamAId, teamA).or().eq(MatchInfo::getTeamBId, teamA)) .and(w - w.eq(MatchInfo::getTeamAId, teamB).or().eq(MatchInfo::getTeamBId, teamB)) .apply(start_time BETWEEN {0} AND {1}, startTime, endTime);这条查询的意思是“查找同一时间段内A队或B队已经存在的未开始比赛”查到了就提示赛程冲突。SQL条件比较多建议在数据库里给match_info表的team_a_id和team_b_id分别建普通索引否则数据量一大查询会变慢。比分录入的逻辑相对简单但要有事务保证录入比分时先更新match_result表然后把match_info的状态置为FINISHED再根据胜负关系更新winner_id。这三个操作必须加Transactional否则会出现“比分录了但比赛状态没变”的不一致问题。事务注解要加在Service层的public方法上不要加在Controller层这是很多同学容易犯的错。4.4 排名统计与Dashboard数据如果系统里有循环赛积分排名是绕不开的功能。排名数据最好不实时聚合而是通过SQL直接计算得到结果集然后放入一个RankingVO里。积分排名的核心SQL思路大概是SELECT team_id, SUM(is_winner 1) AS wins, SUM(is_winner 0) AS losses, SUM(score) AS total_score FROM match_result WHERE team_id IS NOT NULL GROUP BY team_id ORDER BY wins DESC, total_score DESC这里is_winner是match_result表里的字段胜利记1失败记0。胜场数相同时比较净胜分净胜分可以用SUM(score) - SUM(lost_score)来算前提是你把对手分数也存到了表里。Dashboard统计一般包括赛事总数、战队总数、进行中的赛事数本月新增用户数等。这些统计值不需要单独建表用聚合查询就够了long totalEvents eventMapper.selectCount(null); long runningEvents eventMapper.selectCount(new LambdaQueryWrapperEvent() .eq(Event::getStatus, EventStatus.RUNNING.getCode()));前端图表展示可以用ECharts后端只需要提供一个统计接口把数据组装好返回JSON。这一块是最容易拿高分的地方因为很多同学的毕业设计只有表格没有图表你做一个参赛项目占比饼图和战队胜率柱状图视觉上就拉开了差距。4.5 自定义异常与统一返回格式接口返回格式如果不统一前端处理数据会非常痛苦。建议定义一个ResultT通用返回体public class ResultT { private Integer code; private String message; private T data; // 成功/失败静态方法 }Controller所有方法都返回Result对象配合全局异常处理器RestControllerAdvice把校验异常、业务异常、未知异常都转成统一格式。这样一个列表接口出错时前端拿到的永远是{code:500, message:赛事不存在, data:null}不用到处做类型判断。全局异常处理器里的关键点是区分“业务异常”和“系统异常”。业务异常比如状态流转非法、战队名重复返回code400提示信息给用户看系统异常返回code500日志记录堆栈但返回给前端的信息要模糊化不要泄露SQL细节。5. 前端页面与接口对接经验5.1 页面组织方案模板引擎还是前后端分离电竞赛事管理系统的前端有两种做法一是用Thymeleaf服务端渲染页面直接由SpringBoot托管结构简单适合不想写前端代码的同学二是用Vue实现前后端分离前端独立部署通过Axios调后端接口代码组织更现代工作量更大但更适合作为亮点写进简历。如果你的毕业设计时间不足三周我建议用Thymeleaf加Bootstrap。原因是后端代码就是考试重点前端能用模板渲染搞定的话只要复制一套后台管理界面模板改改表单和表格绑定就行逻辑集中在后端答辩时讲起来也更顺。如果选Vue方案需要解决跨域问题。在SpringBoot后端配置CorsFilter即可明确允许的前端源地址Configuration public class CorsConfig { Bean public CorsFilter corsFilter() { CorsConfiguration config new CorsConfiguration(); config.addAllowedOrigin(http://localhost:5173); // 前端开发服务器地址 config.addAllowedMethod(*); config.addAllowedHeader(*); config.setAllowCredentials(true); UrlBasedCorsConfigurationSource source new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration(/**, config); return new CorsFilter(source); } }5.2 前端调用接口的几个建议如果自己写前端建议把请求统一封装成一个axios实例在请求拦截器里自动带上Tokenaxios.interceptors.request.use(config { const token localStorage.getItem(token); if (token) { config.headers.Authorization Bearer ${token}; } return config; });响应拦截器里统一处理code不为200的情况弹出错误提示。这样每个页面的请求代码会非常简洁业务逻辑不会乱。列表页建议后端接口接收current和size参数返回分页数据前端直接渲染records和total字段。不要每次把全量数据都查出来数据量大了页面会卡顿面试/答辩时被问分页实现也能展示你对系统性能有考虑。6. 常见问题与排查实录6.1 分页查询查不到数据的坑用MyBatis-Plus的selectPage时如果返回的total一直是0大概率是Mapper接口没有继承BaseMapper或者实体类上的TableName注解值写错了导致MyBatis-Plus不知道查哪张表。还有个小概率问题是分页插件没有配置PaginationInnerInterceptor在MyBatis-Plus较新版本中需要显式添加该Bean否则分页SQL不会自动拼接LIMIT。6.2 日期时间格式永远对不上前后端时间显示相差8小时或格式不对先检查两个地方一是MySQL的连接URL里有没有serverTimezoneAsia/Shanghai二是SpringBoot的Jackson配置里time-zone是不是写了GMT8。如果你用了Fastjson或Jackson但配置没统一也会出现序列化格式不一致的问题。最省事的做法是所有时间字段在实体类上用JsonFormat(pattern yyyy-MM-dd HH:mm:ss, timezone GMT8)显式标注前端拿到的一定是格式化好的字符串不依赖全局配置。6.3 事务注解失效代码没报错但比分修改后比赛状态没更新大概率是Transactional没生效。检查两点方法是不是public的是不是在同一个类里通过this.method()调用自身方法Spring的事务是通过代理实现的同类内部调用不走代理注解就失效了。解决方法是把需要事务的逻辑拆到另一个Service类里或者通过AopContext.currentProxy()获取代理对象调用。6.4 逻辑删除导致唯一索引冲突用户表配了逻辑删除但删除用户后重新注册同名用户会报唯一索引冲突。因为逻辑删除只是把deleted置为1记录还在表里唯一索引依然约束着用户名。解决方法有三种把唯一索引改成(username, deleted)联合索引删除前先查有没有未删除的同名用户或者注册时在SQL里手动排除deleted1的记录。实际项目里最常用的是联合索引方案。6.5 接口返回N1查询问题赛事列表页显示“已报名战队数”如果先在Service层查出赛事列表再循环遍历查询每场赛事的战队数就产生了N1查询数据量一多接口就会变慢。正确做法是先用一个SELECT event_id, COUNT(*) FROM team WHERE event_id IN (...) GROUP BY event_id的聚合查询把所有计数拿回来再用内存映射关联到VO上。这个优化在答辩时提出来面试官通常会点头。6.6 项目启动报错Bean无法创建最常遇到的是MyBatis-Plus的Mapper接口没有被扫描到。启动类上要加上MapperScan(com.example.mapper)注解或者在每个Mapper接口上标注Mapper。前者更推荐一次搞定不用给每个接口加注解。7. 写在最后的个人体会做这种课程设计/毕业设计类型的项目本质上是把你学过的东西串成一条线让它能跑、能演示、能讲出逻辑。我个人在实际操作中的体会是别把时间花在追求花哨的页面和炫技的代码上把最核心的几件事做扎实——表结构设计合理、状态流转有逻辑、接口返回规范、常见的坑提前绕过这个项目就已经是优良水平了。最后再分享一个小技巧答辩前把项目跑起来准备好十来个操作路径比如“创建一个赛事→添加战队→创建对阵→录入比分→查看排名”全程录个短视频存着。万一现场投影设备出问题直接放视频演示既专业又稳妥。如果你正在做这个题目按照上面的思路一步步来源码、数据库、文档这些配套内容自然会跟着完善起来祝顺利。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Linux之Http<3>--表单 2026/9/28 18:53:17

Linux之Http<3>--表单

之前的代码编写,都是对网站资源的请求,等等 ,那些都是对于静态资源的获取但是还存在动态内容的获取,比如动态站点,支持用户进行登录,注册,支付,查找等功能功能静态资源请求 VS 动态请求1. 静态资源请求目标:.html、.png、.css、.js这类文件特点:文件内容…

阅读更多 →
用好 Pi:一份来自官方文档与社区实战的深度技巧指南 2026/9/28 18:53:17

用好 Pi:一份来自官方文档与社区实战的深度技巧指南

用好 Pi:一份来自官方文档与社区实战的深度技巧指南 如果你已经被各种 AI 编程 Agent 的"全家桶"压得喘不过气——臃肿的系统提示词、点不完的权限弹窗、永远猜不到它在想什么的"黑盒"——那么 Pi(pi.dev)可能是你一直在…

阅读更多 →
立创EDA + AI 生成 STM32 原理图教程:用 TaoToken 统一 Key 打通配置链路 2026/9/28 18:53:11

立创EDA + AI 生成 STM32 原理图教程:用 TaoToken 统一 Key 打通配置链路

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

阅读更多 →
OpenClaw 插件架构解析:从核心原理到 TaoToken 配置落地 2026/9/28 18:53:11

OpenClaw 插件架构解析:从核心原理到 TaoToken 配置落地

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

阅读更多 →
本地运行 OpenClaw 实操教程:Windows 下自动化办公 AI 工具搭建与 TaoToken 配置指南(含安装包) 2026/9/28 18:53:11

本地运行 OpenClaw 实操教程:Windows 下自动化办公 AI 工具搭建与 TaoToken 配置指南(含安装包)

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

阅读更多 →
从嘉立创EDA到AD:PCB 3D模型精准定位与结构验证全流程 2026/9/28 18:53:04

从嘉立创EDA到AD:PCB 3D模型精准定位与结构验证全流程

搞硬件设计的朋友应该都有过这种经历:PCB画完只是第一步,元器件高度对不对、外壳开孔位置准不准、接插件会不会和结构件互相顶住,这些靠眼睛看二维图纸根本看不出来。我自己的习惯是从嘉立创EDA/立创商城直接拿元器件的3D模型(STE…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉