ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

SpringBoot+MySQL构建汽车售后质量管理系统实战

SpringBoot+MySQL构建汽车售后质量管理系统实战 做汽车售后质量管理系统的时候我遇到最多的问题就是“你为什么不用微服务”“为什么还死守着MySQL”说实话这类疑问我一开始还会认真解释后来就只回一句——你先把SpringBoot单体跑明白了再说。这个标题里把SpringBoot误写成了SprintBoot反而让我觉得很真实因为很多人对这个项目的认知就停留在“跑通增删改查”的层面根本没摸到汽车售后质量管理系统的真实业务痛点。这套系统的核心价值不在于技术栈有多新而在于它把汽车售后场景里的质量追溯、客户投诉闭环、索赔结算、维修质检给完整串了起来。用SpringBoot做应用层承载MySQL做数据存储与统计这套组合在单店或区域型售后网络的数据量下性能完全够用而且团队好招人、部署简单、出了问题也好排查。这篇文章我会从业务需求选型、数据库设计、核心代码实现、报表与索赔模块、实战踩坑复盘五个方向展开把我在做这个系统时的完整思路和落地细节写清楚适合正在做类似管理系统的Java后端开发、汽车行业IT从业者以及想搞明白SpringBootMySQL到底能扛多少事的同学。1. 业务需求与选型复盘为什么这套系统用SpringBootMySQL就够了1.1 汽车售后质量管理到底管什么汽车售后质量管理不是一个模糊的概念落到系统功能上它主要是四件事质量工单流转、维修质检记录、客户投诉闭环、索赔与结算管理。每个4S店或者售后服务中心每天都会产生大量需要跟踪的数据——客户报障、维修工单、配件更换记录、终检结果、厂家索赔申请这些数据如果靠Excel和微信来回传基本是管不住的。质量工单是整个系统的流转中枢。客户反映车辆异常售后前台登记录入系统生成工单然后派给维修技师技师完成作业后由质检员终检终检合格才能交车如果涉及索赔还得走索赔申请流程。这一整条链路的状态变化、操作人留痕、时间节点都需要系统记录下来。另一个重要维度是质量追溯。比如某批次刹车片出现异常磨损系统要能查到这个批次的配件用在了哪些车上、哪些工单里、车主是谁、索赔状态如何。没有一套结构化的管理系统这种追溯基本做不了。1.2 拒绝过度设计单体应用如何支撑售后业务很多同学一听到“系统”两个字就条件反射要上微服务、上消息队列、上分布式事务。我可以负责任地说汽车售后质量管理系统在绝大多数场景下都不需要这些。我们估算一下数据量一个中等规模的售后服务商一个月新增质量工单大概在500到1500条维修工单可能到3000到5000条一年的数据量在5万到10万条哪怕积累五年也就几十万条。这个量级下MySQL单库单表配合合理的索引设计查询响应时间完全可以控制在毫秒级SpringBoot单体应用单机部署压测时并发支撑200到300的在线用户也没有压力。微服务解决的是团队协作和独立扩展问题而售后质量管理系统的开发团队可能只有两三个人部署环境可能就是一台云服务器或者内网服务器。强行拆微服务只会增加网络开销、运维成本和故障排查难度。SpringBoot单体All in One打一个Jar包丢到服务器上就能跑出问题看一个日志文件就行这才是真正适合这个场景的架构。1.3 MySQL在项目中的边界MySQL在这个系统里承载的是结构化业务数据和统计报表的查询。为什么不用Oracle因为授权费用对于一个内部管理系统来说太高了。为什么不用PostgreSQL对于这个业务体量MySQL和PG在功能层面没有本质差别但团队里会MySQL的人明显更多招聘成本和沟通成本更低。需要说明的是MySQL不是万能的这个项目里我也划清了它的边界。比如工单备注、客户反馈这种大文本字段我用的是TEXT类型但不在这些字段上建索引全文检索需求我用LIKE %关键词%配合前缀索引策略就能解决大部分场景。假设将来数据量真的突破百万级并且有复杂搜索需求到时候再引入Elasticsearch也来得及现阶段没有必要为一个不确定的未来做过度设计。2. 数据库设计质量追溯链路如何落到表结构上2.1 业务路径梳理先行建表之前我花了两天把业务路径画清楚。这个环节太重要了很多项目失败不是因为代码写得烂而是表结构没有贴合业务路径。整理后的核心路径有两条。第一条是质量工单路径客户投诉或内部抽检发现问题登记生成质量工单工单进入待受理状态售后经理派工给维修班组维修完成后由质检员进行质检登记质检通过后工单归档闭环如果涉及配件质量问题则发起索赔流程。第二条是索赔结算路径索赔申请单提交后由技术经理审核审核通过后上报厂家或供应商厂家结算完成后财务核销生成索赔结算记录。设计表结构的时候我要求自己做到每一个表都能在这两条路径上找到它存在的理由每一个关键状态连接点都有对应的表和字段。不需要为了“功能丰富”去加表也不需要为了“设计华丽”去造无意义的冗余字段。2.2 七张核心表的设计与字段说明整个系统的数据模型我最终收敛为七张核心业务表加上用户权限等基础表。下面把这七张表的关键字段结构列出来附上设计理由。第一张是车辆档案表vehicle_info它承载的是“这辆车是什么车”这个基本面。核心字段有车辆VIN码、车牌号、品牌车型ID、车系、购买日期、保修状态。VIN码是全车唯一标识也是后续所有追溯查询的连接键。这张表设计时有一个关键点VIN码必须建唯一索引因为售后业务涉及车辆唯一性校验没有唯一索引兜底重复录入会把追溯链路直接打断。第二张是客户信息表customer_info记录车主姓名、电话、联系地址、车辆ID。这张表和vehicle_info是一对多关系一个客户名下可能有多辆车但一辆车在同一时间段内原则上属于一个客户。设计时我把客户ID放在vehicle_info表里做冗余这样查车辆档案时不用每次都JOIN客户表减少一次关联查询。第三张是质量工单表quality_work_order这是整个系统的核心。字段包括工单号、车辆ID、客户ID、投诉描述、质量分类编码、状态、优先级、受理人、派工人、受理时间、期望完成时间、实际完成时间、关闭时间、创建时间、更新时间。工单号用业务规则生成比如日期序列号保证在业务层面可读且唯一。第四张是维修工单表repair_record记录维修执行明细。字段有工单ID、维修项目编码、维修内容、故障现象、故障原因、配件更换记录、维修技师ID、工时费用、配件费用、维修开始时间、结束时间。维修工单和质量工单是一对多关系一个质量工单可能对应多个维修工单因为一次报障可能涉及多个维修项目。第五张是质检记录表inspection_record承载终检留痕。字段有工单ID、质检员ID、质检结果、质检意见、质检时间、是否复检、复检结论。这张表是质量闭环的最后一环没有质检记录的工单不允许闭环。第六张是索赔申请表claim_apply字段有申请单号、工单ID、车辆ID、索赔类型保修索赔/供应商索赔/保险理赔辅助、索赔金额、责任方编码、提交人、审核人、审核状态、厂家受理状态、提交厂家时间、厂家回执编号、创建时间。第七张是索赔结算表claim_settlement记录最终结算信息字段有结算单号、索赔申请ID、结算金额、结算时间、收款账户、发票号、财务确认人、核销状态。结算表和申请表是一对一关系通过申请ID建立唯一关联。这七张表构成了从“问题出现”到“维修处理”到“质量确认”再到“索赔结算”的完整数据链条。用表格汇总一下表名核心角色关键外键/关系业务的不可替代作用vehicle_info车辆档案customer_id车辆唯一标识与基础信息customer_info客户档案无车主联系信息quality_work_order质量工单vehicle_id, customer_id质量问题的受理与流转中枢repair_record维修工单work_order_id维修执行明细与配件追溯inspection_record质检记录work_order_id维修质量终检留痕claim_apply索赔申请work_order_id发起与追踪索赔流程claim_settlement索赔结算claim_id结算金额确认与核销2.3 索引设计的三个关键决策表结构定下来之后索引设计是数据库性能的第一道防线。我这里踩过不少坑挑三个最关键的决策来说。第一个是复合索引的列顺序。质量工单表最常见的查询条件是“某个售后网点在某时间段内产生的工单”对应条件就是dealer_id和create_time。我建了一个复合索引(dealer_id, create_time)查询时先用dealer_id缩小范围再用create_time排序。如果顺序反过来查询优化器在筛选网点时就用不上这个索引性能会下降很多。第二个是尽量利用覆盖索引。查询工单列表页时我只需要工单号、车辆VIN码、客户名、状态、创建时间这几个列在表里建了一个包含这些字段的覆盖索引查询时直接从索引返回数据不需要回表。列表页的响应速度从原来的200多毫秒降到了20毫秒以内这个优化效果非常明显。第三个是不要在索引列上做函数运算。有一次排查慢查询发现一条SQL执行了3秒多看EXPLAIN发现type是ALL。原因是在WHERE条件里写了YEAR(create_time) 2024MySQL对这个条件没法走索引只能全表扫描。改成create_time 2024-01-01 AND create_time 2025-01-01之后执行时间瞬间回到几十毫秒。这个坑非常典型我在后续开发中定了一条规矩索引列禁止套任何函数。3. 核心功能实现从工单登记到质量闭环的代码链路3.1 质量工单的状态机设计质量工单整个生命周期涉及多个状态我用状态机来管理流转。状态定义为一个枚举类包括UNASSIGNED待派工、PENDING待受理、PROCESSING维修中、INSPECTING待质检、PENDING_CONFIRM待客户确认、CLOSED已闭环、REJECTED已驳回。状态流转不是随意跳转的比如维修中的工单不能直接跳到已闭环必须经过待质检。这个约束我在Service层做了统一校验。每个状态流转方法里第一步做的就是校验当前状态是否允许执行该操作。比如finishRepair方法要求工单必须处于PROCESSING状态否则直接抛出业务异常。这里有一段简化的核心代码展示状态校验的逻辑public void finishRepair(Long workOrderId, Long currentUserId) { QualityWorkOrder order qualityWorkOrderMapper.selectById(workOrderId); if (order null) { throw new BusinessException(工单不存在); } // 状态机校验只有维修中才可以完成维修 if (!WorkOrderStatus.PROCESSING.equals(order.getStatus())) { throw new BusinessException(当前状态不能执行该操作); } order.setStatus(WorkOrderStatus.INSPECTING.getCode()); order.setRepairFinishTime(LocalDateTime.now()); qualityWorkOrderMapper.updateById(order); // 记录状态流转日志 workOrderLogService.record(workOrderId, WorkOrderStatus.PROCESSING, WorkOrderStatus.INSPECTING, currentUserId); }状态流转日志非常重要。汽车售后业务一旦出现质量纠纷甲方要求提供每一个时间点的操作记录如果没有日志表单靠updated_time字段根本说不清楚。我在设计时加了一个work_order_log表每次状态变化都插一条数据记录操作人、操作时间、从哪个状态到哪个状态、操作备注相当于把整条链路变成了可审计的流水线。还有一个需要注意的点是并发重复提交。比如两个操作员同时点“完成维修”如果没有状态校验可能会把已进入质检的工单又改回维修中。状态机校验加上数据库层面的乐观锁用version字段做CAS更新可以彻底解决这个问题。UPDATE语句里加上WHERE version #{oldVersion}影响行数为0就说明有并发冲突返回提示信息给用户。3.2 事务边界与MySQL事务隔离级别SpringBoot里使用事务最常见的方式就是Transactional注解。这个注解用起来很简单但坑非常多我在项目里就踩过几次。最大的坑是事务范围过大把耗时操作包在事务里导致数据库连接长时间被占用。比如“创建质量工单并推送消息通知”这个场景很多同学会在一个方法上直接加Transactional方法里先插入工单再调用消息推送服务接口。消息推送如果超时事务会一直不肯提交数据库连接池很快就会被耗尽。正确做法是事务只包裹写数据库的操作消息推送放到事务提交之后通过ApplicationEvent异步处理或者直接放在事务方法外面调用。MySQL默认的隔离级别是可重复读REPEATABLE READ这个隔离级别能避免脏读和不可重复读已经被绝大多数业务系统验证过性能损耗非常小。我在做质量工单的金额统计时使用SUM函数配合事务由于可重复读隔离级别下同一事务内多次查询结果一致生成月度统计报表时不会出现金额忽大忽小的情况。财务相关的索赔结算方法事务隔离级别我保持默认关键靠的是行锁和唯一约束来保证金额不被重复计算。在索赔结算表的设计上我对claim_id建了唯一索引这就让多个人同时提交同一笔索赔单的结算时只有一条能成功插入其余的全部抛出DuplicateKeyException在Service层捕获后返回友好提示。3.3 连接池与批量操作的优化SpringBoot 2.x之后默认的连接池是HikariCP这个连接池性能好、配置简单。我最初直接用默认配置上线结果在早高峰集中录入工单的时候出现了获取连接超时的异常。检查后发现默认配置的maximumPoolSize是10对于十几个后台并发操作员的场景极限情况下确实不够。我的调整思路是根据并发峰值和单次业务耗时来估算连接数。假设峰值并发50个请求每个请求平均占用连接200毫秒需要的连接数是50乘以0.2除以1秒约等于10但我预留了2倍缓冲用于应对突刺最终把maximum-pool-size设置为20minimum-idle设置为5空闲连接超时时间设置为10分钟。调整后连接池再没出现过告警。批量操作方面Spring Boot的MyBatis-Plus提供了saveBatch方法如果直接在MySQL JDBC连接串上追加rewriteBatchedStatementstrue参数批量插入性能会有非常明显的提升。不加这个参数之前MySQL会把批量插入拆成一条条执行效率很低加上之后MySQL会重写批量插入语句一次网络往返提交一批数据。实测导入一千条维修记录从原来的8秒降到了1秒以内体验差别非常大。连接串的完整配置大概是这样的spring: datasource: url: jdbc:mysql://localhost:3306/auto_after_sales?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/ShanghairewriteBatchedStatementstrueallowPublicKeyRetrievaltrue username: root password: yourpassword hikari: maximum-pool-size: 20 minimum-idle: 5 connection-timeout: 30000 idle-timeout: 600000 max-lifetime: 1800000这里要特别说明useSSLfalse和serverTimezoneAsia/Shanghai这两个参数。useSSL默认在MySQL 8.0以上版本会尝试建立SSL连接如果服务端没有配置SSL证书连接会报错或者严重超时在自己的内网环境里直接关闭SSL省心又高效。serverTimezone如果不指定容易报“Unknown time zone”或者时间相差八小时的诡异问题。3.4 权限与数据隔离汽车售后质量管理涉及经销商、服务经理、维修技师、质检员、财务等不同角色权限控制不能只做前端按钮的隐藏后端接口必须做数据隔离。我的做法是引入Spring Security JWT做认证授权然后在Service层通过自定义注解AOP做数据权限过滤。具体逻辑是经销商角色只能查看自己店内的数据运营总部角色可以看全部数据。实现上在查询语句的WHERE条件中自动拼接dealer_id 当前登录用户的所属网点ID。如果漏掉这个拼接一个维修技师登录后理论上可以查到全国所有网点的工单明细这在合规上绝对不允许。数据权限过滤我用了ThreadLocal存储当前登录用户上下文AOP切面里解析方法上的DataScope注解如果方法标注了该注解就自动往SQL查询条件里追加数据范围限制。这个方案在单体应用里非常好用代码侵入性小而且不会因为漏写WHERE条件造成越权。4. 报表统计与索赔结算MySQL数据处理能力的合理运用4.1 质量缺陷Top N报表汽车售后质量管理系统如果只有工单录入和流程流转那它只是一个ERM系统。真正体现“质量管理”价值的是数据统计分析。比如月度质量缺陷Top 10报表根据故障现象字段做分组统计输出“制动系统异响”“发动机抖动”“变速箱顿挫”等高频缺陷的排名帮助售后经理制定改善措施。这类报表的核心SQL思路比较直接用GROUP BY分组COUNT计数ORDER BY排序LIMIT限制返回条数SELECT fault_category, COUNT(*) AS cnt FROM quality_work_order WHERE dealer_id #{dealerId} AND create_time 2024-01-01 AND create_time 2024-02-01 AND status CLOSED GROUP BY fault_category ORDER BY cnt DESC LIMIT 10;这里有一个容易被忽略的细节故障分类字段要确保值域统一。售后前台录入信息时如果是自由文本那同一个故障可能被描述成“刹车异响”“制动异响”“刹车响”统计结果就会非常分散Top 10报表失去参考价值。所以建表时我用了故障分类编码字典表前台是下拉选择不是自由文本输入。这是从业务侧保证数据质量的关键。4.2 索赔结算的金额准确性索赔结算模块直接涉及钱对数据准确性的要求非常高。每一笔索赔申请只能有一条对应的结算记录这个约束我在数据库层用唯一索引兜底同时利用MySQL的原子更新特性来保证金额状态一致。核心的“财务确认核销”操作执行的UPDATE语句是这样的UPDATE claim_settlement SET confirm_status 1, confirm_user_id #{userId}, confirm_time NOW(), version version 1 WHERE id #{settlementId} AND confirm_status 0 AND version #{oldVersion};这条语句的巧妙之处在于WHERE条件带了confirm_status 0如果这条记录已经被别的财务人员确认过了影响行数会是0当前用户就能拿到提示“该结算单已被处理请刷新页面”。配合version乐观锁既不会重复核销也不会出现并发覆盖。索赔金额的汇总统计我使用MySQL的SUM和CASE WHEN组合比如统计各责任方当期索赔总额SELECT responsibility_party, SUM(CASE WHEN confirm_status 1 THEN claim_amount ELSE 0 END) AS confirmed_amount, SUM(CASE WHEN confirm_status 0 THEN claim_amount ELSE 0 END) AS pending_amount FROM claim_apply WHERE create_time 2024-01-01 AND create_time 2024-02-01 GROUP BY responsibility_party;这段SQL在一个查询里同时输出了已确认和待确认的金额比查询两次再在Java代码里合并数据要快得多也少了一次网络往返。4.3 存储过程与触发器能不用就不用很多早期的MySQL系统中存储过程是必修课触发器也被认为是保证数据一致性的利器。但在现代SpringBoot ORM的开发模式下我强烈不建议在这套系统里使用存储过程和触发器。首先是维护问题。存储过程的业务逻辑写在数据库里代码版本无法纳入Git管理加上一段存储过程出了问题修改需要直接在生产库操作风险很大。其次是排错困难Java报错可以看日志但存储过程内部执行到哪一步出问题排查起来非常麻烦。第三是性能隐患触发器会在每次INSERT或UPDATE操作时额外执行一段逻辑在批量导入维修记录的场景下触发器会严重影响写入性能。如果你接手一个老项目里面已经有为了处理复杂统计逻辑而编写的存储过程我的建议也是逐步改造存储过程负责的数据处理迁移到Java Service层经过验证后2024年这套系统我没写一个存储过程触发器也一个没有用数据一致性完全靠事务、唯一索引和业务代码里的校验逻辑来保证。4.4 慢查询排查从热搜词到实际调优MySQL相关热搜词里慢查询、锁表、性能调优出现的频率极高说明这是普遍痛点。我在这个项目上线一个月后主动打开了慢查询日志定位到业务运行中的性能瓶颈。开启和查看慢查询的SQL如下-- 查看当前慢查询日志配置 SHOW VARIABLES LIKE slow_query_log; SHOW VARIABLES LIKE long_query_time; -- 开启慢查询日志并设置阈值 SET GLOBAL slow_query_log ON; SET GLOBAL long_query_time 1;设置long_query_time为1表示超过1秒的SQL都会被记录下来。第二天我查看慢查询日志文件定位到一条查询维修工单列表的SQL耗时2.3秒。通过EXPLAIN分析发现repair_record表在work_order_id上缺少索引全表扫描导致排序和关联都变慢。补上索引后这条SQL的执行时间降到了30毫秒。每次排查完慢查询我都会在接口层加一个日志埋点记录每个请求的处理耗时。当用户反馈页面变慢时先看日志里的耗时分布迅速定位是SQL慢还是业务逻辑慢省去了大量盲查的时间。5. 实战踩坑记录与运维复盘5.1 MySQL 8.0安装后最常见的三个问题项目开发环境用的是MySQL 8.0安装配置过程本身不难但配套问题经常会卡住新手。第一个是所谓的“初始密码”问题安装完成后MySQL会在启动日志里生成一个临时密码很多同学找来找去找不到。解决方案是在my.cnf里加一行skip-grant-tables跳过权限验证启动后手动重置密码然后再注释掉这一行重启服务。这个方法要谨慎使用千万别在生产环境配置只能在本地开发环境解决问题。第二个是客户端认证插件的问题。MySQL 8.0默认使用caching_sha2_password认证插件但一些客户端和旧版本JDBC驱动不支持这个插件连接时会报认证失败。解决办法是在创建用户时指定mysql_native_password插件CREATE USER app_user% IDENTIFIED WITH mysql_native_password BY yourpassword; GRANT ALL PRIVILEGES ON auto_after_sales.* TO app_user%; FLUSH PRIVILEGES;如果你用的是新版本的JDBC驱动其实caching_sha2_password是支持的但为了兼容老系统我在混合环境的项目里统一用mysql_native_password省去不必要的沟通时间。第三个是时区问题表现是对比时间时偏差8小时。原因就是连接串没有指定serverTimezoneMySQL服务端默认时区和应用服务器时区不一致。这个问题在上面已经提过解决办法就是在JDBC连接串中显式加上serverTimezoneAsia/Shanghai应用层面再用统一的时间格式进行序列化避免JSON输出时再出一次偏移。5.2 一次“UPDATE后服务超时”的锁问题排查这个坑对我影响很大发生在一次批量更新工单状态的操作中。运营人员通过Excel导入一批历史工单来初始化系统导入程序对每一条记录执行UPDATE操作。运行到一半前端页面突然卡死很多查询类接口也同时超时。排查链路是这样的先看应用日志发现大量“Lock wait timeout exceeded”异常说明是数据库锁等待超时。再用SQL检查当前锁状态-- 查看当前正在运行的事务和锁等待情况 SELECT * FROM information_schema.innodb_trx; SELECT * FROM information_schema.innodb_lock_waits;结果发现导入程序里开启了一个大事务事务内更新了上万条工单记录这些记录加了行锁后一直没提交。其他请求查询这些行的最新状态时因为和更新事务存在锁冲突就一直在等待锁释放等待时间超过innodb_lock_wait_timeout就报错。根本原因是导入程序用了Spring的Transactional注解包住整个批量导入操作导致事务范围过大行锁持有时间过长。解决办法是改成分批提交每100条一个事务快速释放锁。经过优化后导入完成时间反而从原来的十几分钟缩短到了两分钟系统的吞吐量大幅提升。这个案例给我最大的教训是事务不是越大越好行锁持有时间越短系统并发能力越强。5.3 数据库连接池被打满的问题连接池打满也是常见的生产事故。某天售后前台集中录入维修记录页面开始频繁报“Connection is not available, request timed out after 30000ms”。我立刻检查HikariCP的活跃连接数和等待线程数发现问题出在一个统计接口上。这个统计接口在Service层循环遍历了几百家供应商对每家供应商分别发起一个SQL查询计算当月的索赔金额涉及N1次数据库调用。每次查询占用连接的时间虽然短但在并发高峰期叠加起来就把连接池占满了。优化方案是重写这段统计逻辑把循环里的逐条查询合并成一条带IN条件的SQL减少数据库连接占用。同时给这个统计接口加上Redis缓存设置5分钟过期时间因为报表数据本身不需要实时更新。优化后连接池活跃连接数从峰值19降到了6问题彻底解决。5.4 数据归档与备份策略系统上线跑了一年后业务表数据量增长明显虽然还远没到需要分库分表的程度但查询列表页偶尔出现了变慢的迹象。我的解决方案是水平分区加归档而不是改造成分库分表。做法是每个月新建一张带后缀的历史表比如quality_work_order_202401、quality_work_order_202402把三个月之前已闭环的工单数据通过INSERT INTO ... SELECT搬过去。归档只搬状态为CLOSED的数据流程中的工单保留在主表确保在办业务不受影响。查询历史工单时通过MyBatis的动态表名切换到对应的归档表查询。备份策略用了mysqldump加定时任务每天凌晨2点对全库做一次逻辑备份保留最近30天的备份文件mysqldump -u root -p auto_after_sales --single-transaction --routines --triggers /backup/auto_after_sales_$(date %Y%m%d).sql--single-transaction参数确保了备份期间不锁表业务可以继续写入不影响白天的正常使用。这套策略持续跑了半年多没有出现过一次数据丢失的问题。做这个项目最大的感触是技术选型不要追新追高能解决实际问题、团队能驾驭、运维够简单的方案就是好方案。SpringBootMySQL这套组合听起来没有微服务高大上但在汽车售后质量管理这个业务体量下它确实是最稳、最省心的选择。如果你也正在规划类似的系统记住先把业务链路梳理清楚把表结构设计好把状态流转和事务边界控制好这套系统就已经成功了一大半。
返回列表