ARTICLE DETAIL

资讯详情

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

宠物爱心组织管理系统实战:SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0全解析

宠物爱心组织管理系统实战:SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0全解析 开宠物爱心组织管理系统这个坑已经有好几个月了。从最初给流浪动物救助基地搭内部台账到后来做成一套能跑实习生管理、领养审批、物资捐赠登记的系统中间推翻了三次方案。最终定下来的技术组合就是标题里这套SpringBoot2 Vue3 MyBatis-Plus MySQL8.0配上完整文档。这篇文章我把自己从零到一的整个设计思路、核心业务拆解、代码实现细节、部署配置、踩坑记录全盘托出。无论你是因为课程设计、毕业设计还是真的想给身边救助站建一套管理系统这套东西都能让你少走至少两周弯路。1. 内容整体设计与思路拆解1.1 为什么选这四个技术栈而不是更“新”的方案宠物爱心组织管理系统本质上是一个多角色、带审批流、带资源管理的业务系统。市面上很多现成的后台管理脚手架若依、vue-element-admin、Ruoyi-Vue3版本等都能提速开发但我这次刻意选择了自研组合关键是想把控制权完全握在自己手里不被脚手架业务模块里那些用不到的代码干扰。先说后端SpringBoot2现在依然是国内Java Web项目的主力版本。SpringBoot3虽然已经发布多年但对JDK版本要求更高很多学校和企业服务器还停留在JDK8环境。SpringBoot2 JDK8这条组合线下绝大多数云服务器、虚拟主机、老项目的依赖包都能直接兼容。也从实际运维角度验证过2.7.x这个版本线整体稳定性是最好的网上求助帖、解决方案也最全遇到问题一搜就能解决比3.x版本时代少了很多“新坑”。数据层用了MyBatis-Plus而不是原生MyBatis或Spring Data JPA。理由很简单MyBatis-Plus提供的通用CRUD、分页插件、条件构造器能帮我省掉至少60%的重复SQL编写。一个救助基地的宠物信息表、领养申请表、捐赠记录表字段多、状态变化频繁如果用原生MyBatis全手写XML光这些接口就得写两百多行映射文件。而MyBatis-Plus的BaseMapper接口已经内置了insert、deleteById、selectPage等方法我只需定义实体类和Mapper接口不用写一行SQL就能完成基础数据操作。前端选择Vue3一方面是大势所趋另一方面Vue3的组合式APIComposition API确实让代码组织和复用提升了一个量级。这个系统里宠物档案列表、领养审批列表、志愿者任务池这三个核心页面我全都用Composition API把“数据加载”、“状态切换”、“筛选搜索”的逻辑拆成了可复用的hook函数。同样的功能如果用Vue2的Options API写页面一复杂data、methods、computed、watch四处分散后期改一个功能要在组件里上下翻几屏非常难受。MySQL8.0是我在数据库上的选择理由也很实际。社区版免费、资料多、稳定而且8.0在窗口函数、JSON类型支持上比5.7强了太多。宠物救助这种业务场景领养审核记录、志愿者服务时长统计经常会用到按时间窗口排序、分组聚合这类需求8.0能让我用一条SQL搞定用5.7得写多条子查询再加应用层拼接。数据库版本锁定后就能稳定使用utf8mb4字符集加上MySQL8.0默认的utf8mb4_0900_ai_ci排序规则中文存储和查询匹配都很顺畅不用额外配置。1.2 宠物爱心组织系统的核心业务域拆解聊完了技术栈选型重点看业务。这类系统的用户角色通常有三类管理员组织负责人、志愿者/员工一线操作人员、外部用户领养人/捐赠人。在设计模型时我按照“资产、流转、行为”三个维度拆解业务域资产域宠物信息品种、年龄、健康状态、是否绝育、疫苗接种记录、物资信息狗粮、猫砂、药品、资金账户。流转域宠物入库收治/救助→ 宠物在库养护 → 领养申请 → 审核/回访 → 出库领养成功/死亡/放归。这是整个系统最核心的一条状态机。行为域志愿者报名与排班、捐赠记录登记、回访记录填写、活动管理。这三个域之间的关系可以理解为一辆“传送带”宠物被救助进来在库里被志愿者养护同时对外发布领养信息有人提交申请组织方审核确认后宠物出库进入回访阶段整个流程闭环。系统里每个表、每个接口设计都是围绕这条传动链来的。如果只是简单做一个“宠物信息增删改查”那这套系统的价值就打折扣了真正值钱的是它把“救助-养护-领养-回访”这条完整链路数字化了。也是基于这个思路我在数据库里设计了一张核心的宠物状态表和一个领养申请状态表后面所有功能页面几乎都是围绕这两张表的状态流转展开的。2. 核心细节解析与实操要点2.1 数据库表结构设计宠物表和领养表的状态机设计数据库表设计是最值得先花一周磨刀的地方。我初期草率设计直接在宠物信息表里加了 submitStatus、applyStatus、checkStatus 三个字段后来业务一跑发现状态混在一起代码写得非常痛苦。最后推翻重来将状态拆分到不同的表保持每个业务实体状态清晰独立。宠物信息表pet核心字段如下字段名类型说明idbigint主键pet_namevarchar(64)宠物名称pet_typetinyint类型1-猫 2-狗 3-其他breedvarchar(64)品种gendertinyint性别 0-公 1-母age_yearsint年龄岁health_statusvarchar(255)健康状态良好/待治疗/康复中is_neuteredtinyint是否绝育 0-否 1-是is_vaccinatedtinyint是否接种疫苗statustinyint核心状态0-待入库 1-在库养护 2-待领养 3-已领养 4-已离开(死亡/放归)in_timedatetime入库时间out_timedatetime出库时间cover_imagevarchar(255)宠物照片remarkvarchar(500)备注领养申请表adoption_apply核心字段字段名类型说明idbigint主键apply_novarchar(32)申请编号pet_idbigint关联宠物IDapplicant_namevarchar(64)领养人姓名applicant_phonevarchar(20)联系电话applicant_addressvarchar(255)家庭住址family_incomevarchar(64)家庭情况描述has_yardtinyint是否有院子/阳台other_petsvarchar(255)其他宠物情况reasontext领养理由statustinyint0-待审核 1-已通过待签协议 2-已拒绝 3-已完成apply_timedatetime申请时间audit_timedatetime审核时间audit_user_idbigint审核人IDinterview_recordtext回访记录两个表之间通过 pet_id 建立关联。核心设计心得千万不要把申请状态放在宠物表里因为一个宠物可以同时被多人申请只能有一条申请被最终批准需要以申请表为主状态宠物表的 status 只保存最终结果已领养/在库养护/待领养两者通过 re_id 同步。在给宠物执行“上架领养”操作时SQL状态原子更新是关键避免多人同时操作时重复领养同一只宠物Update(UPDATE pet SET status 2 WHERE id #{petId} AND status 2) int updatePetToAdoptable(Param(petId) Long petId); Update(UPDATE pet SET status 3 WHERE id #{petId} AND status 3) int updatePetToAdopted(Param(petId) Long petId);这里加 status 2 或 3 的条件本质上是一次乐观锁控制。Java Web并发请求下两个管理员同时点击“领养成功”按钮第二个人会因为 update 行数为0得知操作失败从而避免同一只宠物被重复领养的情况。2.2 后端通用CRUD服务的实现思路MyBatis-Plus的通用CRUD是提高开发效率的核心但这个“通用”不是无脑地用需要合理封装。我设计了一个如下的 Service 基类public class GpBaseServiceImplM extends BaseMapperT, T extends ServiceImplM, T { public PageT pageList(PageQuery query) { PageT page new Page(query.getPageNo(), query.getPageSize()); QueryWrapperT wrapper new QueryWrapper(); if (StringUtils.hasText(query.getKeyword())) { wrapper.and(w - w.like(name, query.getKeyword()) .or().like(remark, query.getKeyword())); } // 通用排序 if (StringUtils.hasText(query.getOrderByColumn())) { wrapper.orderBy(true, query.isAsc(), query.getOrderByColumn()); } else { wrapper.orderByDesc(create_time); } return this.page(page, wrapper); } }所有业务Service继承这个基类之后宠物Service、志愿者Service、捐赠记录Service只要业务不是特别复杂就只需要一行代码继承然后按需重写几个方法即可。这就是标题中“通用CRUD服务基于MyBatis-Plus工具类实现无状态增删改查”的含义——Service层做到无状态不存会话数据每个方法只依赖入参极大方便了分布式部署和功能扩展。提示不要迷信“通用Service能搞定一切”。真正业务复杂的地方比如领养申请的状态机流转、志愿者排班冲突检测必须在具体的Service里写自定义方法。通用的东西只解决80%的重复问题剩下20%才是系统的灵魂。2.3 前端Vue3实现的页面结构设计与Composition API核心演示Vue3前端的设计我采用的是“页面-组件-hook”三层结构。页面负责路由和布局组件负责数据展示和交互hook负责业务逻辑复用。这比传统Vue2把所有逻辑堆在页面组件里要清晰得多。以领养管理页面为例领养申请列表是整个系统的核心运营页面。我拆分成下面几个文件views/adoption/index.vue页面入口放筛选栏和表格components/AdoptionAuditDialog.vue审核对话框components/AdoptionDetailDrawer.vue申请详情抽屉hooks/useAdoptionList.js领养列表逻辑hook核心hook如下import { ref, onMounted } from vue import { getAdoptionList, auditAdoption } from /api/adoption export function useAdoptionList() { const list ref([]) const total ref(0) const loading ref(false) const queryParams ref({ pageNo: 1, pageSize: 10, keyword: , status: null, }) async function fetchList() { loading.value true try { const res await getAdoptionList(queryParams.value) list.value res.data.records total.value res.data.total } finally { loading.value false } } async function handleAudit(applyId, auditResult, remark) { await auditAdoption({ applyId, auditResult, remark }) await fetchList() // 审核通过后后台会自动把pet状态改为已领养 } onMounted(fetchList) return { list, total, loading, queryParams, fetchList, handleAudit, } }这样设计的好处是当后续需要在“我的领养申请”页面复用相同的列表逻辑时直接引用这个hook就行根本不用改代码。这也是Vue3相比Vue2最大的吸引力——逻辑复用不再是mixin那种隐蔽的合并覆盖方式而是函数的自由选择与组合。2.4 前后端联调注意事项前后端分离项目联调时最大的坑就是跨域和接口规范。两个点必须提前定死第一统一返回结构。我的后端所有接口都返回统一结构{ code: 200, message: success, data: ... }。前端封装axios请求拦截器统一处理这样页面上不用每次写重复的错误处理逻辑。public class ResultT { private Integer code; private String message; private T data; }第二跨域配置。开发环境我用 Vue3 的 vite 代理把/api前缀代理到http://localhost:8080生产环境用Nginx反向代理。CORS配置不要直接allowCredentials(true)allowedOrigin(*)混用这会导致Chrome直接拦截Nginx配置里也需要指定proxy_pass到后端地址。// vite.config.js export default defineConfig({ server: { port: 3000, proxy: { /api: { target: http://localhost:8080, changeOrigin: true, rewrite: (path) path.replace(/^\/api/, ) } } } })3. 实操过程与核心环节实现3.1 环境准备与安装配置一个Windows纯小白视角先从开发环境说起。你不需要什么特别的工具JDK8、Maven3.6、Node.js16、MySQL8.0这四个就够了。IDE我用的是IDEA前端用VS Code。MySQL8.0安装值得单独拎出来讲。最常见的坑是安装过程要求你设置root密码然而下一步下一步之后却连不上。很多新人卡在“MySQL8.0安装”这关所以我给你一个稳妥的流程从MySQL官网下载 MySQL Installer Community选择 Server only 即可省得装一堆用不上的组件。安装到 Configuration 步骤时Authentication Method 一定要选择Use Legacy Authentication。MySQL8.0默认用的 caching_sha2_password 加密方式如果你的JDBC驱动版本不够新mysql-connector-java低于8.0.x客户端连不上会报Authentication plugin caching_sha2_password cannot be loaded。虽然我这里用的是新版连接器但未来你接手其他老项目时这个选择会省掉一小时排查。如果已经装了8.0后期想改认证方式执行ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 你的密码; FLUSH PRIVILEGES;安装完成后用Navicat或DataGrip建一个数据库确保排序规则选择 utf8mb4_0900_ai_ci或者直接执行下面的SQL脚本CREATE DATABASE pet_love_system DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;提示如果你的MySQL8.0是在docker里跑的记得挂载数据卷否则容器一删数据全没了。具体命令不在这里展开了但这个问题问的人极多docker mysql8.0的组合你没有数据卷就等于没存数据。3.2 后端工程结构和启动顺序项目结构采用标准Maven多模块但因为是单体应用我实际用的是单模块内分包com.petlove ├── config // 配置类 ├── controller // 控制器层 ├── service // 业务逻辑层 │ └── impl ├── mapper // MyBatis-Plus Mapper接口 ├── entity // 实体类 ├── dto // 数据传输对象 ├── vo // 视图对象 └── common // 通用返回、异常处理、工具类这一步不要小看一个清晰的分层结构能让你在后面业务扩展时不会一头雾水。尤其要把实体类Entity和视图对象VO分开。我自己曾经图省事直接把实体类返回给前端结果某次给宠物列表加敏感字段“救助人联系方式”直接泄露到前台下个页面了。数据安全不是大工程而是责任心的问题。启动后端时需要先确保 application.yml 里的数据库连接配置正确spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/pet_love_system?serverTimezoneAsia/ShanghaicharacterEncodingutf8useSSLfalseallowPublicKeyRetrievaltrue username: root password: 你的密码 jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT8注意URL里的allowPublicKeyRetrievaltrueMySQL8.0默认使用caching_sha2_passwordJDBC连接时若不加这个参数某些版本会报“Public Key Retrieval is not allowed”错误。启动后端后访问http://localhost:8080/api/pet/list能看到数据就算基础连通了。3.3 前端工程创建与页面搭建前端用Vite创建Vue3项目是最快的。相比webpackVite启动速度快到飞起开发体验提升非常明显。npm create vitelatest pet-love-web -- --template vue cd pet-love-web npm install npm install element-plus axios vue-router4 piniaElement Plus是我最终选择的UI库。搞笑的是刚开始我尝试用Naive UI因为它更现代、TypeScript支持更好但后来因为团队里其他人不熟悉而换成了Element Plus。倒不是说Naive不好而是Element Plus的组件生态更全、中后台方案更成熟稳定。首页整体结构用了侧边栏布局左侧是菜单宠物管理、领养管理、志愿者管理、捐赠物资管理、活动管理、数据统计右侧是路由出口和顶部栏。菜单配置路由用动态生成方式方便不同角色的用户看到不同菜单。比如普通志愿者不显示“数据统计”和“用户权限管理”只有管理员能看到并管理整个系统。下面这个宠物列表页核心展示字段是缩略图、名字、类型、健康状态、当前状态操作列有“编辑”、“上架领养”、“查看申请”。健康状态用el-tag展示颜色区分绿色良好、橙色待治疗、红色急需就诊。状态列则用文字带颜色展示当前所在环节。前端展示细节决定了志愿者日常用的顺手程度这个不能马虎。3.4 关键业务领养审核流程的前后端配合领养审核是最体现业务闭环的功能。我把它拆成了三步第一步用户在前台提交领养申请。领养人信息包括姓名、电话、住址、住房类型自有/租房、家庭成员、是否有其他宠物、领养理由。提交后申请表状态为“待审核”同时关联宠物此时状态可变可不変。我的选择是不变继续保持“待领养”因为可能有多个申请同时挂着审核通过之前不能动宠物状态。第二步管理员审核。管理员进入后台领养列表看到该宠物的全部申请。如果通过后台执行两件事一是更新申请表状态为“已通过待签协议”二是把宠物状态更新为“已领养”相当于锁定了宠物不让后面的申请者重复申请。如果拒绝申请表状态直接变成“已拒绝”宠物继续在“待领养”池里等待下一个申请者。第三步协议签署与回访。领养人线下签署领养协议之后管理员上传协议附件并把申请表状态更新为“已完成”。之后在“回访管理”里定期填写回访记录确认宠物在新家的生活情况。整个状态流转我用一个枚举类进行管理避免魔法数字到处乱飞public enum PetStatus { PENDING_IN(0, 待入库), IN_CARE(1, 在库养护), ADOPTABLE(2, 待领养), ADOPTED(3, 已领养), DEPARTED(4, 已离开); private final Integer code; private final String desc; }枚举的好处后面写定时统计报表时也体会到了。用枚举的 code 作为数据库存值desc 作为展示文案前端的字典映射也统一用这个枚举生成保证前后端状态名词永远一致。3.5 数据统计看板MySQL窗口函数的实际应用系统里还有一个值得提的数据统计看板。做看板之前我以为得用复杂的聚合SQL后来发现那个需求用窗口函数写极其丝滑。比如某个月每个志愿者服务时长的累计统计SELECT volunteer_id, volunteer_name, service_date, service_hours, SUM(service_hours) OVER (PARTITION BY volunteer_id ORDER BY service_date) AS cumulative_hours FROM service_record WHERE YEAR(service_date) 2025 ORDER BY volunteer_id, service_date;由于开发选择了MySQL8.0窗口函数开箱即用统计在SQL层直接解决应用层一行Java逻辑都不用写数据返回速度也非常快。这完全是从MySQL8.0拿到的红利换到5.7上这段SQL直接废了得写变量累加。提示如果以后部署环境不允许MySQL8.0那么类似的排序分组统计SQL需要通过子查询用户变量去实现效率和可读性都会大打折扣。定数据库大版本之前一定要想清楚业务里有多少统计需求。4. 常见问题与排查技巧实录4.1 数据库连接报错Connection refused 和 Authentication plugin这套系统部署到别人电脑上时数据库连接类的问题占到了80%。最常见的是两种。一个是Access denied for user rootlocalhost (using password: YES)基本就是密码不对。但有一种隐蔽情况是密码包含、%等特殊符号在YAML配置中没加引号导致解析错误。YAML中密码建议统一用双引号或单引号包裹避免这类隐性问题。另一个就是前面提到过的Authentication plugin caching_sha2_password cannot be loaded如果出现这个直接改认证插件为 mysql_native_password或者升级mysql-connector-java依赖到8.0.11以上版本改完后重启后端即可。4.2 Vue3项目启动报错Cannot find module vue这个错误大多不是Vue没装而是模块依赖没正确安装。你clone项目后如果只安装了根目录依赖而后端前端的嵌套目录没有install就会出现找不到模块。确认进入前端目录执行 npm install且Node版本和项目要求一致Node16以下跑Vue3大概率报各种语法错误建议直接用Node 18 LTS。还有一种少见但恶心的情况是package-lock.json 里锁了旧版本依赖新环境执行npm install只会安装锁定的旧包而旧包和新的Node版本不兼容。处理办法是删掉 node_modules 和 package-lock.json 重新安装。4.3 MyBatis-Plus分页插件不生效PaginationInnerInterceptor配置缺失新人对MyBatis-Plus最常见的误解是只用引入了MyBatis-Plus依赖分页查询就生效。实际要生效必须配置分页插件Configuration public class MybatisPlusConfig { Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } }不配置的话使用 selectPage 虽然不报错但查出来的全表数据里再内存分页数据量大时页面直接卡死。很多人查代码查了半天发现分页没生效最后知道是少了这个插件那种心情我太理解了。4.4 前端跨域配置后依然无法请求到后端如果使用了Vite代理前端代码里请求路径最好统一写成相对路径/api/pet/list而不是写死http://localhost:8080/api/pet/list。如果把域名端口写死在 axios 的 baseURL 里代理转发就对不上号了请求会直接从浏览器发出前端项目的代理形同虚设。排查跨域问题时打开浏览器F12关注请求URL到底是http://localhost:3000/api/xxx还是http://localhost:8080/api/xxx。如果是后者代理肯定没生效如果是前者但还是出现跨域报错就在Nginx或后端把允许的 Origin 域名端口精确配置上。4.5 常见问题速查表现象可能原因解决方案启动后端报Access denied数据库密码错误或用户权限不足检查application.yml密码确认root远程权限前端页面接口全部404后端未启动或端口不一致确认后端启动成功检查代理target端口分页查询返回全量数据MyBatis-Plus分页插件未配置添加PaginationInnerInterceptor中文显示乱码字符集配置错误URL加characterEncodingutf8MySQL库字符集为utf8mb4图片上传失败上传目录权限不足或配置路径错误检查静态资源映射路径与写入权限审核通过后宠物状态未更新事务未提交或未同步修改pet表检查Service层Transactional和关联更新逻辑菜单权限不可见路由未按角色动态生成检查Router动态addRoute逻辑和角色标识4.6 系统联调阶段的日志排查技巧开发中最实用的排查工具还是日志。我的经验是每天项目跑起来第一件事就要确认日志级别可调。开发环境日志级别调成DEBUG查看SQL执行日志生产环境切回INFO避免日志刷屏。MyBatis-Plus要打印SQL在 application.yml 加如下配置mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl假如审核宠物接口执行成功但数据库状态没变核心排查思路就是拿到这个接口的完整SQL日志看看 UPDATE 语句影响的行数是0还是1。如果行数是0说明WHERE条件没匹配上大概率是状态字段判断不对或乐观锁冲突如果行数是1但页面没刷新出预期结果那就是前端重新拉取列表时缓存了旧数据。日志能帮你把问题精准定位到前后端各自的领域。我还要强调事务的重要性。领养审核通过时涉及到更新申请表状态、更新宠物状态、写审核日志这三步操作必须全部在同一事务中。任何一步失败都要整体回滚否则会出现“申请通过了但宠物还在待领养”的数据错乱。我的Service方法上统一加了Transactional(rollbackFor Exception.class)注意括号里的参数很关键如果不写默认只在运行时异常时回滚检查异常如IOException是不会回滚的。5. 项目文档与二次开发经验5.1 含文档的意义文档对系统和人的价值这个系统标题里特别标注了【含文档】我觉得这是这个项目最大的加分项。文档的价值等到发生人员交接时才会被真正感受到。我有一次接手的系统没有文档光摸清状态字段含义、定时任务逻辑、第三方接口对接就花了两周。而这次我为 pet_love_system 写了三份核心文档设计文档包含需求分析、ER图、接口文档、数据库建表SQL。部署文档包含MySQL8.0安装、SpringBoot2打包部署、Vue3前端构建部署、Nginx反向代理配置。用户操作手册给基地志愿者的图文操作教程减少日常被问“这个怎么弄”的概率。写文档的过程中也反过来帮我补齐了很多代码细节。比如写“捐赠物资入库操作流程”时就发现自己漏了物资类别管理功能于是赶紧把代码补上。从这个角度看文档不只是给别人看的更是项目自检的工具。5.2 如何基于该项目做二次开发很多技术人拿到这套系统后会想往里面加功能。典型的二次开发方向有下面几个。第一增加微信小程序端。前端用uni-app对接Vue3的API逻辑直接复用现有接口即可。小程序端主要面向普通用户浏览待领养宠物、提交领养申请、在线捐赠。核心是API权限控制需要增加微信登录鉴权不能让外部用户直接访问管理后台接口。第二增加数据大屏。宠物爱心组织非常需要公开透明展示救助成果数据大屏可以实时展示累计救助数量、领养成功率、志愿者工时、物资库存周转率。数据大屏技术选型可以用ECharts MySQL统计SQL前端Vue3引入echarts包即可。第三增加自动备份与通知。设计一个定时任务每天凌晨备份数据库到指定目录再对接邮件服务给组织负责人发送日报日报包含新增宠物数、新增领养申请数、待办审批数等关键指标。5.3 快速部署到服务器的实际配置过程服务器部署我推荐用最朴素但稳妥的方式前端构建后由Nginx托管静态文件后端打成jar包用systemd管理。前端构建命令非常简单npm run build构建完成后dist目录里的文件直接扔到服务器的/opt/pet-front目录下Nginx配置如下server { listen 80; server_name your.domain.com; location / { root /opt/pet-front; index index.html; try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://127.0.0.1:8080/api/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }后端打包和启动mvn clean package -DskipTests nohup java -jar pet-love-system.jar --spring.profiles.activeprod /opt/pet-love/logs/app.log 21 这里补充一个profile切换的点开发环境用application-dev.yml本地数据库生产环境用application-prod.yml服务器数据库。资源文件下建多个配置文件启动参数根据环境指定别把本地密码和线上密码写在同一个文件里。6. 实操心得与项目复盘这个项目从零开始到完全跑通我的体会有三点。第一状态机设计是一套管理系统的地基。如果宠物状态和领养申请状态之间没有一个清晰的流转约束系统越到后期越难维护。最初的表设计里我甚至在宠物表里塞了一个“是否为热门领养”的字段后来发现这个字段和状态耦合太深运营同学维护起来极其痛苦最终拆成了标签表。凡是涉及到多状态、多角色审批的业务第一周时间值得全花在画状态图和流程图上而不是急着写代码。第二技术栈的选择要为“未来的维护者”考虑。如果你一个人写代码用最新技术随你开心。但管理系统这种东西大概率会有第二个人接手。SpringBoot2 Vue3 MyBatis-Plus MySQL8.0这个组合算是这个时代主流且均衡的选择上一个SpringBoot1.5时代的老项目被维护者骂了无数遍我不想制造一个未来的“老项目”让大家吐槽。第三别迷信“一套代码走天下”。宠物爱心组织管理系统这种项目本质上是对整个救助业务的数字化业务逻辑永远比技术重要。比如宠物状态里的“已离开”我一开始用的是“死亡”后来被组织方负责人强烈建议改掉因为“死亡”这个词在对外展示和内部心理感受上都太沉重改成“已离开”后同事们接受度明显更高。这不是矫情而是软件设计对业务场景的真实尊重。最后再说一个落地技巧如果你是拿这个项目做毕业设计演示时一定要先准备好演示数据别用空的数据库现场表演但数据也不要太假。提前录好一份从“宠物入库 → 志愿者养护 → 上架领养 → 用户申请 → 管理员审核通过 → 填写回访记录”的完整流程演示时按照这个路径点过去比临时翻菜单找功能要有说服力得多。如果是要投入到真实组织中运行建议先搭一套试用环境跑两周让一线志愿者把日常遇到的不顺手、不合理的交互反馈上来集中改一版后再正式上线。这样的系统才是活的而不是代码整洁但没有温度的玩具。
返回列表