尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Spring Boot流浪动物救助及领养管理系统设计与实现攻略

Spring Boot流浪动物救助及领养管理系统设计与实现攻略 每个找你谈毕设题目的学生十个里有七个开口就是SpringBoot但真要问到“你的流浪动物救助及领养管理系统到底管到什么程度”很多人就卡住了。这个题目如果只是把动物表的增删改查堆完其实只能算做了一半——救助、领养、捐赠三条业务线互相牵扯动物生命周期从救助进站到送养回访、再到退养回流每个状态都要有据可查。如果你是准备毕业设计的计算机本科生或者想用一个规范项目练手SpringBoot全栈开发这篇文章会给你一套能直接落地的方案技术选型怎么定、表结构怎么设计、前后端怎么对接、演示时哪些环节最容易翻车。1. 先把这个题目的“考点”拆清楚系统到底要做成什么样1.1 题目里藏着的三个业务模块先说结论流浪动物救助及领养管理系统这个题目表面上拆成救助、领养、捐赠三个词实际上对应着三条独立的业务线。很多同学拿到题目第一时间就去写动物信息的增删改查写到一半发现不对劲动物的状态怎么流转领养申请被驳回之后动物应该是什么状态捐款记录跟救助站的开销怎么对得上这些问题如果一开始没想清楚后面改起来非常痛苦。所以第一步不是写代码而是把题目翻译成“系统用例集合”。我建议把它拆成三个模块来理解救助站内部管理模块动物档案包括物种、品种、性别、大致年龄、毛色、体重救助信息包括救助地点、救助日期、救助人描述健康信息包括疫苗情况、驱虫记录、是否绝育、当前体检状态以及员工对动物日常状态的维护。这个模块是后台内务主要由管理员和救助站员工使用。在线领养模块面向公众。所有人可以浏览待领养的动物列表和详情注册用户可以填写领养申请管理人员审核申请审核通过后预约到站核实线下签订领养协议并在系统中登记领养记录之后还能记录回访信息。这个模块是给“普通人”用的也是演示时最出效果的部分。爱心捐赠模块捐赠人查看求助信息和捐赠项目发起捐赠订单线下或模拟支付后平台记录捐赠资金后台登记资金使用情况形成“收入—支出”可查询的台账。这个模块会让项目业务完整度明显上一个台阶因为如果只有前端捐赠页面、没有资金流水和用途记录评委一眼就能看出是在凑页面。把这三块做完整个题目才算被真正承接住而不是一个花架子。1.2 用户角色划分与核心业务流程角色我建议划分成三类不加第四类平台管理员管理员工账号、审核领养申请、审核捐赠项目、查看资金台账、维护系统公告。救助站员工负责动物档案录入和维护、更新健康状态、登记领养协议和回访、登记捐赠支出。注册用户浏览动物、申请领养、查看进度、发起捐赠、查看捐赠记录。为什么不让角色更多因为每一类角色都对应菜单权限、接口鉴权、页面设计角色一多开发量成倍上涨。毕业设计要在有限时间内做深做透三类角色完全足够。核心业务流程我建议先画一张“动物生命周期状态图”而不是直接画ER图。一只流浪动物从进站开始大致会经历这样几个状态待接收/待体检刚救助回来还没开始体检或检疫观察待领养体检通过、疫苗驱虫完成可以展示在前台供用户浏览已领养用户通过申请、到站核实、签订领养协议退回/再次送养原领养人因故无法继续喂养退回救助站因病离世救助站记录去向这个状态虽然不好看但它是真实业务的组成部分。状态流转图一旦确定领养模块的代码逻辑就会跟着清晰申请领养时要检查动物状态是不是“待领养”审核通过后要同时更新申请表状态和动物状态退回时要把动物重新改为“待领养”。这些业务规则不需要多高深的技术但必须在设计阶段明确否则写接口时就靠现场拍脑袋。1.3 毕业设计评委最关注的四个点答辩时评委并不会真的去看你写了多少行代码他们通常从以下四个视角判断项目成不成立业务逻辑是否闭环。从动物进站到被领养再到回访能不能完全走通捐赠资金有没有去向记录。这是最核心的。技术栈是否用得合理。用了Spring Boot就自然会被问有没有分层、有没有统一异常处理、有没有权限控制。有没有“亮点功能”。定时任务、状态机、文件上传、数据统计图表有一两个成型亮点比堆砌十个普通CRUD更有说服力。答辩现场能不能稳定运行。前端能打开、数据能加载、核心流程能一口气演示完就基本能拿到不错的成绩。明确了这四点后面每一章其实都是在为这四点服务。2. 技术栈选型和项目骨架搭建稳定比炫技重要2.1 Spring Boot版本那么多毕业设计选哪个每年都有同学来问Spring Boot版本太高了怎么办我的建议非常直接本科毕业设计优先选择Spring Boot 2.7.x JDK 8/11 MySQL 8.0 MyBatis-Plus 3.5.x。这个组合是教程资源最丰富、踩坑最少、启动最快的搭配。Spring Boot 3.x确实很新也支持虚拟线程这些特性但它要求JDK 17起步依赖版本变化很大很多老的整合资料已经对不上。大学阶段一个毕设项目核心是业务实现而不是尝鲜框架没必要为了“新版本”给自己埋定时炸弹。MyBatis-Plus是我个人强烈推荐的持久层框架。它提供通用Mapper、通用Service分页查询有内置插件字段自动填充也支持省去大量手写SQL。尤其在这个项目里动物列表要按品种、状态、性别做多条件筛选用LambdaQueryWrapper可以写得很清爽。如果你对底层好奇它本质上就是基于MyBatis做了一层CRUD封装配合Spring Boot的自动装配机制你只需要扫描到Mapper接口实现类就会自动注册进容器。这个原理以后面试被问到也有得聊。前端我建议Vue 2或Vue 3加Element UI或Element Plus。为什么引入前端框架因为只做后端接口不做一个管理系统演示效果会比较单薄。时间紧张就用Vue加Element搭后台管理布局再补一个面向访客的动物展示页面完整度就够了。2.2 项目分层思维Spring Boot项目的分层我的建议是不要自作聪明堆一堆自定义文件夹老老实实按约定分层com.example.animal ├── controller // 接口层只做参数接收和结果返回 ├── service // 业务层具体规则在这里写 │ └── impl ├── mapper // 数据访问层继承BaseMapper ├── entity // 数据库实体类 ├── dto // 接口入参对象 ├── vo // 返回给前端的对象 ├── config // 配置类跨域、拦截器、文件上传映射等 ├── common // 统一返回结果、异常处理、工具类 └── task // 定时任务Controller里不要写业务逻辑比如“判断动物状态再决定能不能申请领养”应该放在Service层而不是写在接口方法里。很多人图省事直接在Controller里堆if else等接口多了改一个审核逻辑要翻遍好几个文件。同时建议定义统一返回结构。前端统一判断code不需要每个接口单独解析错误。配合全局异常处理整个项目接口风格会很一致代码评审和论文截图看起来都专业很多。2.3 把Vue打包结果塞进Spring Boot最常见的部署方案是前后端分开部署后端跑一个Spring Boot进程前端用Nginx托管dist目录再配置反向代理把/api转发给后端。这个方案生产环境没问题但放在毕业设计场景会增加部署复杂度。我更推荐一个“自己够用”的方式前端构建后将dist目录下文件复制到Spring Boot的src/main/resources/static再把这套工程打成jar。最终交付物只有一个jar包启动就是完整系统。实际操作很简单# 前端项目根目录执行 npm run build # 得到 dist 目录把 dist 下的内容复制到后端 static 目录 # 后端执行打包 mvn clean package -DskipTests java -jar target/animal-0.0.1-SNAPSHOT.jar访问 http://localhost:8080 就能直接看到系统页面。这个做法在演示环境、离线和答辩现场非常实用不用现场配Nginx也不用解释复杂端口转发。第6章会再展开部署细节。3. 数据库设计三张主表带你理清整个业务3.1 动物档案表生命周期管理的地基animal表是整个系统的中心表建议字段如下字段名类型说明idbigint主键IDanimal_namevarchar(50)动物名字救助站起的昵称speciesvarchar(20)物种猫、狗等breedvarchar(50)品种gendertinyint0未知 1公 2母age_monthint年龄月定时任务每日更新hair_colorvarchar(50)毛色weightdecimal体重(kg)health_statusvarchar(50)健康状态描述vaccine_statustinyint是否完成疫苗sterilizedtinyint是否绝育rescue_addressvarchar(255)救助地点rescue_datedate救助日期shelter_idbigint所属救助站avatar_urlvarchar(255)封面图img_urlstext多图JSON数组或逗号分隔statustinyint动物状态0待接收 1待领养 2已领养 3退回 4离世create_timedatetime创建时间update_timedatetime更新时间为什么年龄用“月”而不是一个出生日期因为流浪动物的出生日期往往不准确救助站通常只能估算大概几个月大。系统录入估算月龄后每日定时任务加1即可逻辑简单且效果直观。img_urls用text存多张图片路径这在毕业设计里是常见做法。它确实不符合范式的“规整”要求但对一个演示项目足够实用避免了为宠物图片单独建一张表带来的无谓复杂度。3.2 领养申请表与领养记录表的设计领养场景有两个阶段申请阶段和已成档阶段。建议分表。adoption_application领养申请表字段名类型说明idbigint主键animal_idbigint动物IDuser_idbigint申请人用户IDapplicant_namevarchar(50)领养人姓名phonevarchar(20)联系电话addressvarchar(255)居住地址family_membersint共同居住人数has_childrentinyint是否有儿童has_pet_experiencetinyint是否有养宠经验home_conditiontext家庭环境说明reasontext领养理由statustinyint0待审核 1通过 2拒绝 3已完成 4已取消audit_remarkvarchar(255)审核备注audit_timedatetime审核时间create_timedatetime申请时间adoption_record领养记录表字段名类型说明idbigint主键application_idbigint申请表IDanimal_idbigint动物IDuser_idbigint领养人IDadopt_datedate正式领养日期sign_agreementtinyint是否签署领养协议follow_up_contenttext最近回访备注follow_up_timedatetime最近回访时间为什么申请表和领养记录要分开因为一张申请被审核通过后状态可能变成“已完成领养”如果还要在同一张表维护回访内容表结构会越来越乱而且一个“待审核”的申请根本不该有回访字段。拆开之后领养记录只关心“最终交付”和“后续回访”职责更清晰。3.3 捐赠模块的数据结构以及为什么要有订单流水捐赠部分我建议做成“捐赠订单资金用途”的两层结构而不是简单一张捐赠记录表。donation_order捐赠订单表字段名类型说明idbigint主键order_novarchar(64)订单编号唯一user_idbigint捐赠人donor_namevarchar(50)捐赠人姓名amountdecimal(10,2)捐赠金额payment_methodtinyint支付方式1线下捐赠 2微信模拟 3支付宝模拟purposevarchar(255)捐赠用途猫粮狗粮、医疗、疫苗、绝育等statustinyint0待支付 1已支付 2已取消pay_timedatetime支付时间remarkvarchar(255)备注donation_use资金用途表字段名类型说明idbigint主键order_idbigint关联捐赠订单use_typetinyint支出类型1医疗 2口粮 3疫苗驱虫 4绝育 5其他amountdecimal(10,2)支出金额use_descvarchar(255)支出说明use_timedatetime支出时间operator_idbigint经办员工为什么需要order_no因为它能让你在演示“捐赠明细”时给出一个非常真实的流水号也方便多平台对账。为什么需要donation_use因为“只有收入没有支出去向的系统在答辩时经不住深挖”。有了用途表你甚至可以在管理端统计本月捐赠收入多少钱、猫粮采购花了多少、医疗花了多少这些数据稍加转换就能喂给ECharts做图表又是一个答辩亮点。3.4 索引、外键和枚举字段的经验设计表时有两类常见问题一是要不要物理外键二是状态字段存什么。物理外键在我这个项目的建议是“不要加”。不是说外键不好而是MySQL在删除和修改时会受外键约束毕设演示过程中你可能要手动清理测试数据一旦外键缠住删一只动物得先把申请、记录全部删干净非常麻烦。更常见的做法是“逻辑外键”表里保留animal_id、user_id这些关联字段但不声明FOREIGN KEY约束靠代码逻辑保证数据一致性。论文里写一句“为了降低耦合、方便业务扩展系统采用逻辑外键设计”就能说明你想过这个问题。索引方面给这些字段加普通索引足够animal_id因为多表查询高频JOINuser_id申请和记录表都用到status列表筛选高频条件adoption_application的create_time列表按时间排序。状态字段存什么强烈建议存数字代码不要存中文“待审核”“已通过”。原因很简单状态将来可能改名只要数字不变前端字典配置改一下就行存中文的话改一个名称要动数据库、后端代码和前端判断逻辑。项目里约定好状态枚举统一写在常量类或前端字典里代码会清爽很多。4. 后端核心功能实现把流程串起来4.1 JWT认证与权限拦截用户登录后后端颁发JWT前端保存在localStorage每次请求在Header携带Authorization: Bearer token。后端用一个拦截器统一验证Token并解析出当前用户ID和角色。拦截器核心逻辑大致如下Component public class JwtInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String uri request.getRequestURI(); // 放行登录、注册、动物列表、详情等公开接口 if (uri.startsWith(/api/auth/) || uri.startsWith(/api/animals/page) || uri.startsWith(/api/animals/detail)) { return true; } // 解析Authorization头验证JWT失败返回401 String token request.getHeader(Authorization); // ... return true; } }有一个细节很关键很多毕设项目把“管理员操作”和“普通登录”混在一起只要登录了就能修改动物、审核申请。答辩时被问到“权限控制怎么做”就会尴尬。建议至少分两级普通用户能访问个人信息、申请领养、发起捐赠admin或shelter角色才能操作管理相关接口。实现方式可以自定义一个注解也可以直接在Controller方法里判断角色枚举。选最简单的方式就好别过度设计。4.2 动物照片上传与访问路径动物档案系统绕不开图片上传。本地开发时最直接的方案是配置一个上传目录把图片保存在本机磁盘再把访问路径映射给Spring Bootfile: upload-dir: /Users/me/animal-images/ access-prefix: /api/files/**配置类里注册资源映射Configuration public class WebMvcConfig implements WebMvcConfigurer { Value(${file.upload-dir}) private String uploadDir; Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler(/api/files/**) .addResourceLocations(file: uploadDir); } }上传接口实际做三件事接收MultipartFile、把文件写到指定目录并用UUID重命名避免冲突、把最终访问URL例如/api/files/20250512/abc.jpg保存到动物表的avatar_url字段。这里有个极易踩的坑如果直接把文件写进项目的src/main/resources/static目录开发时能访问但执行mvn clean package时上传的图片会被清理掉演示时全部消失。所以一定要把文件存到项目外部的独立目录再把路径映射配好。改造更大一点可以接入MinIO提供对象存储和可访问URL但毕设阶段把本地文件存储做扎实即可。如果你在论文里写了MinIO就要能答出为什么用对象存储、分桶、临时签名这些细节否则容易被追问。4.3 领养状态机与审核接口领养的状态变化是典型的状态机我建议把状态流转逻辑收拢到Service方法里避免散落在多个接口中。“用户提交领养申请”的示例public boolean applyAdoption(AdoptionApplyDTO dto) { // 1. 查处动物当前状态 Animal animal animalMapper.selectById(dto.getAnimalId()); if (animal.getStatus() ! AnimalStatus.TO_BE_ADOPTED) { throw new BusinessException(该动物当前不可领养); } // 2. 检查用户是否已申请过同一只动物且未完成 Long count adoptionApplicationMapper.selectCount(Wrappers.AdoptionApplicationlambdaQuery() .eq(AdoptionApplication::getAnimalId, dto.getAnimalId()) .eq(AdoptionApplication::getUserId, dto.getUserId()) .in(AdoptionApplication::getStatus, 0, 1)); if (count 0) { throw new BusinessException(你已提交过领养申请请耐心等待审核); } // 3. 生成申请记录暂不改动物状态等审核通过再改 return true; }审核接口的逻辑更复杂审核通过把application.status改为1同时把animal.status改为“已领养”。这里有个小细节——审核通过后是立刻改动物状态还是等“领养人到站确认并签协议”再改真实业务里两者有差异因为审核通过不等于动物已经领走。不少毕设为了演示简单把两者合并从“审核通过”直接到“已领养”。两种都行关键是你要能说清自己为什么这么设计。审核拒绝application.status改为2填写audit_remarkanimal.status维持“待领养”不需要联动。用户取消申请application.status改为4同样不改动物状态。为什么反复强调“动物状态不能随便改”因为状态是列表筛选的依据“待领养”会展示在前台“已领养”要隐藏。一旦你随意修改列表就会出现奇怪的数据。把所有状态变化集中在确定的方法里项目出错概率会低很多。4.4 捐赠订单生成与模拟支付逻辑真正的微信支付需要商户号、证书、回调地址毕业设计基本不具备条件。所以我们的做法是生成订单然后提供一个“模拟支付”按钮。生成订单的核心String orderNo DN System.currentTimeMillis() RandomUtil.randomNumbers(4);订单状态为“待支付”。用户在页面点击“确认支付”后前端调支付接口后端校验订单归属人后直接把这笔订单状态改为“已支付”同时记录pay_time。为了更像真实流程校验逻辑不要省。答辩被问到“为什么不做真实支付”可以这样回答在线支付涉及资金安全和商户资质认证校内演示项目重点在于业务流程完整性所以使用模拟支付如果后续上线可以替换为微信支付V3统一下单接口并把支付成功回调地址指向本系统。这样说评委就知道你理解业务边界。4.5 定时任务更新动物年龄与状态提醒这里是我认为整个项目里性价比最高的“亮点”之一。Spring Boot的Scheduled只需在主启动类加EnableScheduling然后在某个Service里写每日任务。Component public class AnimalStatusTask { Scheduled(cron 0 0 2 * * ?) // 每天凌晨2点执行 public void updateAnimalAge() { // 把所有正常状态的动物age_month加1 // 更新数据库 } }另外可以做到期提醒假如为动物维护了“下次疫苗时间”或“体检到期时间”每天检查一次距离到期不足3天的数据生成一条提醒列表。演示时切到后台看到“今日待办提醒”整个系统的专业度立刻不一样。定时任务不需要实现得多复杂只要逻辑正确、结果能显示就已经是完整的技术亮点。5. 实测中踩过的坑跨域、拦截器和日期序列化写这套项目时我自己也踩了不少坑下面这四个问题是问得最多的我按完整排查链路写下来。5.1 跨域配置把前端和后端都坑了一次从Vue使用8080端口请求后端8080端口浏览器会产生跨域问题。一开始我以为在Controller加一个CrossOrigin就完事结果每个接口都要加很麻烦。后来改成全局配置Configuration public class CorsConfig { Bean public CorsFilter corsFilter() { CorsConfiguration config new CorsConfiguration(); config.addAllowedOriginPattern(*); config.addAllowedHeader(*); config.addAllowedMethod(*); config.setAllowCredentials(true); UrlBasedCorsConfigurationSource source new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration(/**, config); return new CorsFilter(source); } }注意allowCredentials(true)允许携带Cookie和认证信息但一旦设置为trueallowedOrigins就不能用必须使用addAllowedOriginPattern()。这是我踩得最惨的一个点写成allowedOrigins(*)又同时开allowCredentials结果请求一直不对。如果生产环境用Nginx做反向代理同一个域名下不会有跨域这个知识也可以写进论文的一段补充说明。5.2 拦截器没有放行OPTIONS导致登录失败加了JWT拦截器之后我遇到一个诡异现象登录接口明明写在排除列表里前端请求还是报错。打开浏览器控制台才发现请求变成了两个第一个是OPTIONS预检请求。原因是前端在Authorization头里放了Token浏览器在正式请求前会先发一个OPTIONS请求询问接口允不允许这个Header而我的拦截器把所有非公开接口都拦下来OPTIONS请求直接返回401。解决很简单在拦截器里对所有OPTIONS请求直接返回true或显式放行OPTIONS方法。这一步不处理好项目本地没问题部署到服务器后登录就失败而且排查方向往往先怀疑跨域实际上卡在拦截器。5.3 日期格式化跑到前端变成时间戳的怪问题后端LocalDateTime直接返回到前端有时会变成一个很长的数字这是Jackson默认序列化导致的。解决方式有两种一种是在实体字段加JsonFormat(pattern yyyy-MM-dd HH:mm:ss, timezone GMT8)另一种是全局配置ObjectMapper统一日期格式。我建议用全局配置否则实体一多每个字段都加注解容易漏。timezone必须写不写默认时区可能差8个小时演示时创建时间会让人心慌。5.4 图片删不掉和打包后消失的坑这个问题和第4.2小节是同一问题的正反面。如果把图片保存在项目target目录执行mvn clean之后target被清空图片全部消失。如果保存在src/main/resources/static目录下面重新打包编译后static里新增的图片也可能没了。再次强调图片必须存到“项目进程之外”的目录例如D:/animal-images或者/opt/animal-images。最好在配置文件中把目录和访问前缀作为变量维护这样jar包稳定不动图片在磁盘上独立保存重新打包也不受影响。6. 打包部署、答辩准备和后续扩展建议6.1 一次打包部署的完整步骤毕业设计最终交付我强烈建议实现“单个jar包部署”而不是答辩现场开两个终端跑前端和后端。操作步骤前端项目执行npm run build得到dist把dist下的所有静态文件复制到后端src/main/resources/static检查后端配置中的数据库连接、文件上传目录、JWT密钥改成运行环境可调整的配置执行mvn clean package -DskipTests把jar包和一份初始化SQL建库建表语句基础测试数据一起打包提交部署机器安装JDK版本8或11和MySQL导入SQL修改application.yml里的数据库账号密码执行java -jar animal-xxx.jar启动。这里有两个容易忽略的点。第一数据库连接信息不要写死在代码里放到application.yml中演示机器换数据库时可以临时改第二提交给老师的材料里一定包含数据库初始化脚本。很多老师会下载项目到本地运行如果缺了SQL脚本整个项目打不开损失非常大。6.2 答辩演示时的数据准备与演示脚本答辩前一定要准备测试数据不能只在系统里留一条“张三”。我的建议往系统录8到10只不同状态的动物其中故意安排2只“待领养”、1只“已领养”、1只“退回待处理”再放几条捐赠订单和几条资金用途记录。这样评委随机提问你都有现成数据可以讲。然后是演示脚本强烈建议按一条主线走访客身份打开首页展示动物列表和详情注册账号或登录已有账号选择一只“待领养”的动物提交领养申请切换管理员账号在待审核列表看到这条申请审核通过回到前台看到动物状态变成“已领养”再演示捐赠流程发起一笔捐赠、模拟支付、后台看到订单最后展示定时任务或统计图表作为收尾亮点。每一步切换越流畅越好建议在答辩机器上完整走三遍以上。电脑接投影仪后分辨率会变化页面布局容易乱要提前检查。6.3 论文写作中容易被追问的细节论文里ER图、用例图、系统架构图都不能少但更重要的是图中信息的自洽。比如ER图里画了animal和adoption_application有直接关系那你的字段设计里就必须有对应的外键字段用例图里给管理员画了“审核领养”系统里就必须有这个入口。很多论文被当场问倒不是因为功能不对而是因为图和代码对不上。技术方案部分建议明确写清“为什么选用这个技术”而不是只列技术清单。例如选用MyBatis-Plus是因为内置通用CRUD和分页插件减少重复SQL选用JWT是因为无状态、适合前后端分离状态字段用数字枚举是为了避免中文导致扩展困难。这些理由在论文里非常提气。6.4 如果还想加功能短信通知、AI识别、微信捐赠时间和精力允许的话项目可以在这三个方向扩展按性价比排序领养进度通知审核通过后通过邮件或站内信通知领养人。毕设接不了真实短信服务可以做系统站内信加WebSocket推送演示效果也够。更智能的搜索对宠物描述做关键词匹配可以引入HanLP分词做搜索词预处理让搜索结果更符合语义。这也是一个和Spring Boot整合的好素材。真实支付把模拟支付升级成微信支付V3需要商户号和回调地址。毕设阶段未必能申请到商户号所以论文里写“预留支付接口后续可无缝替换”即可。这些都属于锦上添花核心稳定才是基础别让扩展功能盖过主线。最后说点实在话。我见过太多同学在这个题目上一开始兴致勃勃想做一堆功能最后崩溃在环境搭建上。我的建议是选题之后第一周先写数据库表和核心状态流第二周把登录、动物列表、上传图片跑通后面再逐个模块叠加。这样即便中途遇到问题手里也已经有一个能跑的版本。希望这份从题目拆解到落地部署的完整过程能帮你把这个项目做得又快又稳。
返回列表