ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

万仙山旅游管理系统实战:Spring Boot+MyBatis+Redis完整设计

万仙山旅游管理系统实战:Spring Boot+MyBatis+Redis完整设计 先说结论如果你是准备拿它当毕业设计或者想找一个能完整跑通“前后端分离 业务系统设计”的练手项目这个题目很适合。万仙山是河南新乡辉县著名的太行山水景区名字听着像旅游网站实际要做的是一套典型的“后台管理 前端展示 预订交易”三合一系统。这类题目的难点从来不是技术本身而是你不知道哪些功能该做、做到什么程度才让评委觉得“工作量够了、逻辑闭环了”。我结合实际开发经验把这套系统从模块划分、表结构设计、核心技术点到答辩时最容易翻车的地方完整拆一遍。如果你手里拿到的刚好是类似“某某景区旅游管理系统”的题目这篇文章的思路可以直接平移过去。1. 这个题目到底考察什么拆解万仙山旅游管理系统的核心模块1.1 别被“旅游管理系统”骗了本质还是CRUD的四种境界很多同学看到“旅游管理系统”就以为要做地图导航、景点AR导览、行程智能推荐结果埋头研究了半个月高德API发现根本整合不进去项目也做不完。实际上毕设级别的旅游管理系统考察的核心永远是**“基于角色的资源管理与交易闭环”**。所谓资源管理就是景区有几类核心资源景点、酒店、餐饮、旅行团线路、导游人员。所谓交易闭环就是游客从注册登录 → 浏览产品 → 下单预订 → 支付/模拟支付 → 生成订单 → 消费核销 → 评价反馈整条链路走通。这条链路上每个环节都能对应一张表、一组接口、一个前端页面这就是你的工作量。万仙山最出名的有郭亮村挂壁公路、绝壁长廊、丹分沟、南坪等景点这些资源天然适合做“景点管理”和“线路管理”模块。你在系统里写死这些景点数据也是合理的反而比做一个泛泛的“旅游平台”更有真实感。1.2 角色权限设计四类用户是标配别做成一锅粥我建议至少划分四种角色这是系统能否在答辩时“讲出深度”的关键角色核心诉求对应模块游客查询景点、线路、酒店在线预订查看订单进度发表评价前台门户 个人中心景区管理员维护景点、线路、酒店信息处理预订订单管理公告后台管理系统导游/地接查看自己带团的线路、游客名单、出团计划移动端/后台精简版系统管理员用户管理、角色权限分配、数据统计、系统配置系统管理模块很多同学做系统一上来就贪多做了一个“超级管理员”把所有功能塞进去。结果就是游客能发布公告、导游能改门票价格逻辑一团糟。正确的做法是设计五张核心表用户表、角色表、菜单/权限表、用户角色关联表、角色菜单关联表用Spring Security或自写拦截器做权限控制。这样不仅模块清晰答辩时还能解释RBAC设计思路这是加分的。1.3 业务功能落点把“万仙山”三个字用到极致为了让系统不显得像随便糊弄的通用模板你要把万仙山特色揉进功能设计里景点管理除了景点名称、简介、开放时间增加“景点热度排序”“适合游玩时长”“最佳观赏季节”等字段这些直接体现你对旅游业务的理解线路管理设计一日游、两日游的固定线路线路下挂多个景点含“含餐与否”“住宿标准”“出发时间”字段酒店民宿管理万仙山周边郭亮村有很多特色农家院酒店模块就可以支持“农家院类型”“是否含早餐”“淡旺季价格”订单模块支持景点门票、酒店房间、线路套餐三种业务类型在一个订单体系下完成。这些都是实际业务场景里存在的需求写在文档里会显得你做过调研而不是对着表结构凭空想的。2. 技术选型背后的取舍为什么Spring Boot MyBatis就够用2.1 Spring Boot的确是标准答案但你要说得出“为什么”邀请热搜词里能看到大量和Spring Boot相关的搜索比如“Springboot自动装配原理”“Springboot默认使用cglib代理”“Springboot引入外部jar包”等。这说明面试和答辩的高频考点都在Spring Boot的底层机制里而不只是“我用了这个框架”。Spring Boot之所以适合这类项目不只是因为它简化了配置。最核心的是它遵循“约定优于配置”的机制可以做到三个自动自动配置引入spring-boot-starter-web后内嵌Tomcat、Spring MVC、Jackson等依赖自动装配好你只需要写Controller自动装配SpringBootApplication注解下包含EnableAutoConfiguration通过spring.factories加载META-INF下的自动配置类自动管理依赖starter机制把所有兼容的依赖版本打包管理你不需要手动指定每个Jar包的版本号。答辩被问“Spring Boot怎么实现自动配置”是高频题一定要准备好。核心一句回答是“Spring Boot通过EnableAutoConfiguration结合spring.factories机制在项目启动时尝试自动加载场景相关的配置类再配合ConditionalOnClass、ConditionalOnMissingBean等条件注解决定哪些配置生效。”2.2 持久层选型MyBatis还是MyBatis-Plus我的建议从热词里能看到“第1关项目整合 - springboot mybatis”“springboot mybatis 结合 mvc框架设计”这类搜索说明这个技术组合是经典中的经典。但我给你的建议稍有不同单表操作多的场景直接用MyBatis-Plus省下的时间足够你把前端做漂亮一倍。理由很简单维度原生MyBatisMyBatis-Plus单表CRUD手写XML写得多BaseMapper内置方法开箱即用分页查询手写Page类或分页插件配置Page selectPage搞定条件构造器拼接SQL容易出错LambdaQueryWrapper类型安全学习成本低但琐碎会MyBatis就会Plus多花半小时但这里有个反面风险你用MyBatis-Plus用习惯了答辩时老师问一句“这SQL底层怎么执行的”你容易答不上来。所以我的建议是核心表订单、用户、权限的复杂查询用XML手写或写清楚自定义SQL简单的单表增删改查用Plus内置方法。这样在项目展示时你既能说清楚技术也能在源码里讲明白SQL优化。2.3 前端方案Vue分离工程还是Thymeleaf模板别再纠结了从热词看“springboot vue前后端分离”是主流。如果让我直接替你们做决定我推荐没有系统学过前端框架的同学用Thymeleaf学过Vue基础的同学用Vue3 Element Plus Axios两种方案都能过但别各做一半。Thymeleaf方案适合一个人单打独斗页面直接放在Spring Boot项目的src/main/resources/templates下面Controller返回视图名称就能渲染不需要单独起一个Node前端项目。缺点是页面逻辑和数据交互都会堆在服务端代码量会膨胀。前后端分离方案适合你确定能在答辩前把两个项目都部署起来。Spring Boot只负责提供JSON接口Vue项目单独跑在8080端口上代理到8080端口访问后端。交互体验好工作量也大。如果你现在离答辩还有不到两周我强烈建议改选Thymeleaf方案别问为什么我见过太多死在“前端跨域和联调”上的同学。3. 从表结构到业务链路门票、线路、订单这样设计才不走弯路3.1 数据库设计是这组题目里真正拉开差距的地方我刚拆解过毕业设计答辩时老师最常翻的就是你的概念结构设计ER图和逻辑结构设计表结构。很多人的表设计就是景点表、用户表、订单表三张表打天下这绝对不行。带你快速过一遍核心表的设计思路你直接照着设计局部调整就可以。第一类基础资源表景点表scenic_spotid、景点名称、景点简介、图片地址、开放时间、建议游玩时长、热度排序、状态线路表routeid、线路名称、线路类型一日游/两日游、出发时间、价格、是否含餐、是否含住宿、成团人数、剩余名额、详细介绍线路景点关联表route_spotid、线路id、景点id、景点顺序这个表解决“一条线路包含多个景点”的多对多关系酒店表hotelid、酒店名称、酒店类型山庄/农家院/客栈、所在位置、房间总数、淡季价格、旺季价格、设施服务、图片地址。第二类交易核心表用户表userid、用户名、密码BCrypt加密存储、真实姓名、手机号、身份证号实名制购票需求、角色id、创建时间订单表ordersid、订单编号雪花算法生成、用户id、订单类型1门票2线路3酒店、订单总金额、支付状态、订单状态、创建时间、支付时间订单明细表order_itemid、订单id、商品类型、商品id、商品名称、单价、数量、小计金额。为什么一定要拆订单表和订单明细表这是因为你一个订单里可能同时买了“两张成人票一张儿童票”或者一条“含住宿的两日游线路”。如果不拆明细表就只能把两种不同价格塞在同一行里想想都觉得乱。拆开后订单为头、明细为行一组典型的“主子表设计”面试官一看就知道你有真实项目经验。第三类营销与内容表公告表noticeid、标题、内容、发布时间、发布人评论表commentid、用户id、订单id或商品id、评分、内容、回复内容、评论时间、状态收藏表favoriteid、用户id、商品类型、商品id、收藏时间3.2 订单状态流转这里是最容易被追问的“业务层深度”同一条订单会让游客和管理员通过不同身份刷新看到不同状态。这背后是订单状态机的设计。我建议订单状态至少包含5个待支付、已支付/待确认、已确认/待出行、已完成、已取消。支付成功的订单经过管理员确认后进入“已确认”行程结束后可由系统定时任务或管理员手动置为“已完成”。而“已取消”分成两类用户主动取消限定在未支付状态和超时未支付由定时任务自动取消。这个状态机的价值在于你在写订单列表查询时只需要用状态字段做一次条件筛选而不是靠“金额是否大于0”“是否有支付时间”这种间接判断最容易出错。3.3 一个完整的订票链路案例你做出来就能讲透业务拿“游客预订万仙山两日游线路”来说完整的数据流应该是游客在前台选择“万仙山经典两日游”线路点击预订前端POST /route/order请求传线路id、出行日期、出行人数后端Controller接收后先校验用户是否登录再校验剩余名额是否充足Service层生成订单主记录订单编号、用户id、订单类型2、总金额同时生成订单明细生成订单后调用支付模块模拟支付直接生成支付成功回调订单状态改为待确认管理员在后台订单列表中看到这条订单点击确认状态改为已确认导游登录系统后在“我的出团”里能看到该订单对应的游客姓名、电话和出行日期。注意上述链路里“模拟支付”是非常聪明的做法。除非你明确要做微信/支付宝沙箱支付否则不要碰真实支付接口——学生项目里接支付光是商户号申请和相关资质审核就够你折腾两星期了。用支付状态字段模拟并在答辩时说明白“真实生产环境中应接入第三方支付网关本项目考虑到沙箱环境不稳定的因素用模拟支付设计”完全可以说得过去。4. 登录认证与权限控制Spring Security和JWT到底怎么配合4.1 登录方案不做统一后患无穷热词里频繁出现“springboot 签名认证”“springboot远程调用”“springboot自动装配原理”说明认证授权是这个领域最容易被追问的技术点。很多旅游管理系统的需求说明书里会写“实现游客登录注册、管理员权限区分”但如果你用的方案是在每个方法里写if(userType 1)判断那这个项目做完你在技术上是拿不到高分的。我给你的建议是如果采用前后端分离方案使用JWTJSON Web Token做身份认证如果采用Thymeleaf方案使用Spring Security的Session机制。前者无需考虑Session共享问题后者写起来更简单。4.2 基于JWT认证的代码骨架我只给你模板核心是引入两个依赖jjwt或java-jwt和Spring Security可选。如果觉得Spring Security配置繁琐——这也是很多毕设同学的痛点——可以做轻量级方案注册/登录时发放JWT前端请求头携带token后端用一个拦截器统一解析并存入ThreadLocal。我给你一个可以直接用的拦截器核心理路Component public class JwtInterceptor implements HandlerInterceptor { // 从请求头取出token解析后放行否则返回401 Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 放行登录、注册等白名单接口 String uri request.getRequestURI(); if (uri.contains(/login) || uri.contains(/register) || uri.contains(/scenic/list)) { return true; } String token request.getHeader(Authorization); if (StringUtils.hasText(token)) { // 取出用户id存到request attribute后续controller直接用 Long userId JwtUtil.parseToken(token.replace(Bearer , )); request.setAttribute(userId, userId); return true; } response.setStatus(401); return false; } }然后把这个拦截器注册到WebMvcConfigurer里Configuration public class WebConfig implements WebMvcConfigurer { Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new JwtInterceptor()) .addPathPatterns(/**) .excludePathPatterns(/user/login, /user/register, /error); } }注意上面这处逻辑如果接口是前台公开浏览接口要记得放行如果是后台管理接口还需要加角色校验。为了安全考虑游客下单时必须登录——直接在Controller里从request.getAttribute(userId)取当前用户id没有userId就拒绝下单。4.3 密码存储与“记住登录状态”的小坑有一个非常容易翻车的点是很多同学把用户密码直接明文存在数据库里。一旦被老师或评审看到直接印象分大减。正确做法是使用BCryptPasswordEncoder。Spring Security自带这个类单独引入spring-security-crypto包也能用// 注册时加密存储 String encodedPwd new BCryptPasswordEncoder().encode(rawPassword); // 登录时校验 boolean matches new BCryptPasswordEncoder().matches(rawPassword, user.getPassword());还有一个容易忽略的细节JWT设置过期时间时我建议设24小时加7天续签机制或者干脆设置24小时过期、过期后强制重新登录。不要设置成永久token答辩时说“永久token会造成安全隐患”这句话又是个小加分项。5. 热门场景实战把Redis给进去系统性能立刻上档次5.1 没上缓存的项目总感觉少点技术含量在热搜词里有好几条都是关于Redis的比如“springboot整合redis”“若依框架 springboot 集成tdengine 和mysql”。只要你把Redis加入这个旅游管理系统并且在文档和答辩时能解释明白缓存链路的逻辑这个项目的技术广度会明显更扎实。景区旅游系统的典型高频场景是景点的详情信息、线路列表查询频率高但更新频率极低适合缓存热门景点的热度排名可以用Redis的ZSet实现实时排行短信验证码可以用String结构存储设置60秒过期用户的购物车/收藏夹用Hash结构存储user:id作为key。5.2 缓存穿透、击穿、雪崩答辩高频三件套你至少说清一个有些同学怕答不上来干脆不加Redis。其实加了Redis反而要准备应对“缓存穿透、缓存击穿、缓存雪崩”这三问。你不用三个都说得头头是道能把一个场景结合项目说透就足够。以最常见查景点详情为例我给你一个可以直接背下来的设计public ScenicSpotVO getScenicDetail(Long id) { // 1. 先查Redis缓存 String key scenic:detail: id; Object cached redisUtil.get(key); if (cached ! null) { return JSON.parseObject(cached.toString(), ScenicSpotVO.class); } // 2. 缓存未命中查数据库 ScenicSpot spot scenicSpotMapper.selectById(id); if (spot null) { // 3. 防止缓存穿透设置空值缓存 redisUtil.set(key, {}, 60); return null; } // 4. 回写缓存设置超时时间 随机偏移 redisUtil.set(key, JSON.toJSONString(convert(spot)), 60 new Random().nextInt(30)); return convert(spot); }这段代码用空值缓存解决了“缓存穿透”用随机过期时间解决了“缓存雪崩”。至于击穿可以说“本项目热点数据预加载上线前将热门线路缓存预热到Redis中”——这又是一个能拿出来讲的点。5.3 一台电脑上Redis和Spring Boot的整合配置整合步骤我快速给一套不出错的版本在pom.xml引入依赖dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-redis/artifactId /dependency dependency groupIdorg.apache.commons/groupId artifactIdcommons-pool2/artifactId /dependency修改application.ymlspring: redis: host: localhost port: 6379 password: 123456 # 如果有密码就填 lettuce: pool: max-active: 8 max-idle: 8 min-idle: 0写一个RedisUtil工具类封装set、get、expire、increment等方法。这里提醒一句如果你电脑上启动的Redis版本过高或者说Spring Boot版本太高比如2.7.x以后lettuce连接池参数和旧版配置可能有差异。遇到连不上或者TypeException先检查引入的spring-boot-starter-data-redis版本是否和Spring Boot父版本匹配再检查Redis配置是否有credentials认证字段。6. 部署上线与答辩准备从IDEA到服务器每个环节都有坑6.1 IDEA创建Spring Boot项目时就要选对依赖从热搜词能看到“idea 2026 怎么配置springboot服务 编辑配置数据 比如启动端口”“idea创建springboot项目”。这里我猜你想问的是怎么在IDEA里把服务启动端口、上下文路径配置好。新项目框架搭起来时我们分两步走创建项目时在Spring Initializr选择依赖Spring Web、MyBatis/MyBatis-Plus、MySQL Driver、Lombok、Validation、Redis可选项目创建完成在application.yml配置端口和上下文server: port: 8080 servlet: context-path: /wanxianshan配置后接口请求路径会变成http://localhost:8080/wanxianshan/user/login。如果你只写/就不需要加context-path。IDEA里配置启动项的细节是打开Run/Debug Configurations确认Spring Boot的Main Class是你Application类Program arguments和Active Profile不用填除非你要按环境区分配置。6.2 版本不匹配问题Spring Boot版本太高反而会让你欲哭无泪热词里有个“springboot版本太高”这话在毕设场景里太真实了。一个最扎心的场景你选了个Spring Boot 3.5.x或更高版本然后发现原来的javax.servlet变成jakarta.servletMyBatis-Plus的starter不再兼容Redis连接工厂的包名也变了。等你修这些兼容性问题时可能已经耗掉两三天。我的建议非常明确除非你本身是Java老兵否则毕设项目直接选Spring Boot 2.7.x稳定版配合JDK 8或JDK 11。这套组合是网上教程最多的几乎所有问题都能搜到答案。如果你想用更新版本比如Spring Boot 3.x必须配JDK 17你要有自己排查问题的能力。6.3 Maven构建和打包部署的完整流程热词里还有“javamaven项目构建方法springboot”和“docker部署springboot项目”这两件事其实是毕设从“能跑”到“能演示”的分水岭。如果你只是在本机IDEA里点一下运行给老师看那浪费了这个环节的得分点。带着项目走到Docker部署是很好的加分项。走到部署这一步流程是本机测试完整通过后在pom.xml里确认packagingjar/packaging执行Maven命令mvn clean package -DskipTests在target目录下得到xxx.jar如果服务器上有Java运行环境直接java -jar xxx.jar --spring.profiles.activeprod如果你要用Docker写一个DockerfileFROM openjdk:8-jdk-alpine COPY target/wanxianshan.jar app.jar ENTRYPOINT [java, -jar, /app.jar]值得注意的是如果你用了Redis、MySQL在Docker部署时要把它们放在同一个docker-compose网络里并在application-prod.yml里修改连接地址为容器服务名而不是localhost。这个坑很多同学会踩到时候怎么都连不上数据库心态崩溃。6.4 答辩现场最容易暴露的问题现在开始提前准备答辩和面试的高频问题我按经验列一张准备清单建议你每条都准备好一至两句话的回答问题方向参考回答口径为什么用Spring Boot简化配置、自动装配机制、生态成熟、便于快速开发项目JWT和Session区别无状态、适合前后端分离服务端不用存储会话Session在集群下需要共享方案订单表为什么拆主表和明细表一个订单可以包含多个不同价格产品遵循数据库范式避免冗余多角色权限怎么控制RBAC模型用户-角色-菜单多对多关联后端用拦截器/注解校验角色分页查询怎么实现的MyBatis-Plus的Page对象或手写LIMIT offset可以做一层通用返回结果封装项目中遇到的最大难点建议准备一个真实踩坑比如“Redis缓存穿透时怎么设计空值缓存”7. 项目结构规划目录摆对了代码怎么写都顺7.1 分包结构不用纠结高深架构但必须清晰很多同学拿着项目不知道builder目录该建多少个。我给你一个稳妥又常见的分包逻辑com.wanxianshan ├── controller // 接收请求返回Result统一响应 ├── service // 业务逻辑接口 │ └── impl // 业务逻辑实现 ├── mapper // MyBatis Mapper接口 ├── entity // 数据库表对应实体类 ├── dto // 前端接收参数模型 ├── vo // 前端返回视图模型 ├── config // 配置类拦截器、CORS、MyBatisPlus配置 ├── common // 通用返回Result、异常处理、常量 ├── utils // JwtUtil、RedisUtil等工具类 └── WanxianshanApplication.java统一返回结果类Result是最容易被忽略但必须有的东西。否则你会出现“这个接口直接返回Map那个接口直接返回一个String”的混乱状态。正确做法是public class ResultT { private Integer code; private String message; private T data; // 省略getter/setter public static T ResultT ok(T data) { ... } public static T ResultT fail(String msg) { ... } }7.2 Controller层只做“翻译”不写业务判断Controller层是个经典翻车区。我看到过很多同学把金额计算、状态判断、权限校验全写在Controller里最后Controller代码600多行。这是不对的。Controller只做三件事接收前端参数RequestBody DTO或RequestParam调用Service层方法返回Result封装。业务判断全放在Service层比如“下单时校验库存”“支付时校验金额一致性”“评价时校验该用户是否买过此单”。这样你的Service层才有话能讲答辩的时候你能说出来“我把业务校验放在Service层是为了避免Controller过度膨胀以及多个Controller复用同一个核心逻辑”这也是合格的工程思路。7.3 前端路由和页面清单做前先列出来如果你选Vue方案核心页面我帮你盘一下你对照着做至少12个页面首页景点推荐、线路推荐、公告景点列表页、景点详情页线路列表页、线路详情页含下单入口酒店列表页、酒店详情页登录页、注册页个人中心页订单列表、收藏、评价记录后台管理页用户管理、景点管理、线路管理、酒店管理、订单管理、公告管理、评论管理统计分析页按景点热度统计、按月份统计订单收入如果时间紧张酒店模块可以不做详情页直接列表页下单。但景点、线路、订单管理这六个模块必须全部做全这是核心。8. 项目之外的加分项测试、文档和演示时的包装8.1 接口测试别只在Postman里点点就算了我建议你在写完所有接口之后至少整理一份接口文档。如果你会用Springdoc或Swagger直接在项目里集成是最省力的dependency groupIdorg.springdoc/groupId artifactIdspringdoc-openapi-ui/artifactId version1.7.0/version /dependency启动项目后访问 /swagger-ui/index.html页面里会自动罗列所有Controller接口。但是Spring Boot版本比较高的情况下springdoc版本也要注意匹配。Spring Boot 3.x需要使用springdoc 2.x版本这个别弄混了。8.2 写一份“说人话”的文档比写满全篇术语更重要毕设文档通常包括选题背景、需求分析、可行性分析、系统设计概念结构/逻辑结构/物理结构、系统实现、系统测试、总结展望。这套模板你们学校如果固定就按学校的来。但我更想提醒的是文档里的“业务流程描述”和“核心功能操作说明”要大写特写不要抄那种“系统采用B/S结构”的套话。“游客购票流程”你可以这样写游客注册并登录系统系统展示万仙山各景点、线路、酒店信息游客选择线路选择出行日期和人数生成订单系统校验成团名额计算总金额生成待支付订单游客执行模拟支付支付成功后订单状态变为待确认管理员在后台确认订单订单变为已确认游客在行程结束后可发表评价系统沉淀评价数据用于推荐排序。这七句话把完整业务闭环说清楚了评审老师一看就知道你真做了系统而不是只在拼接代码。8.3 数据演示的艺术提前种好数据别现场输入答辩翻车的一大类就是现场往数据库输入数据卡半天。我建议你写一个CommandLineRunner或DataInitializer在项目启动时自动往数据库插入基础数据5条以上景点数据如绝壁长廊、郭亮村、丹分沟、喊泉、磨剑峰、南坪5条以上线路数据6条以上酒店/农家院数据2个管理员账号、3个测试游客账号若干订单数据覆盖待支付、待确认、已完成三种状态若干公告和评论数据。体现出这些测试数据页面里不至于空空荡荡。答辩演示的时候直接“刷新页面”就能给评审一种“上线运行很久”的错觉。很实用。9. 最后再分享一个当初我吃亏换来的经验这套系统做完我自己最深刻的体会是不要沉迷在“技术新不新”要沉浸在“业务通不通”。很多同学做这类毕设有种误区非要在系统里塞个Elasticsearch做景点搜索或者是引入MQ处理订单消息结果连基本的下单流程都带着一堆Bug。我见过最稳的毕设往往是那些把Spring Boot MyBatis-Plus Redis三件套玩得明明白白订单状态机完整、权限链路清晰、前后端交互流畅的项目。把这些基础做扎实再把万仙山特色数据和业务揉进去你答辩的底气和分数都会比硬堆技术栈的同学好很多。如果你时间还算充裕再往前走一步在系统里加一个数据统计面板统计每个景点的热度排名、近30天订单走势、各线路的销售额占比。用ECharts画三张图放在管理员首页。这个功能逻辑简单但视觉冲击力极强属于毕设里的“高性价比亮点”。答辩的时候只要你把数据链路来源说清楚——哪张表统计出来的、口径是什么——评审都会觉得你这个系统是完整可落地的而不只是玩具。
返回列表