去年参与某动物保护组织的技术咨询时,发现他们还在用Excel表格管理上百只待领养宠物信息。这种状况在中小型救助机构非常普遍——领养申请混乱、宠物状态更新滞后、志愿者协作困难。这正是我们开发这套系统的现实背景。
这个基于SpringBoot2+Vue3的全栈项目,核心目标是构建一个符合现代Web开发标准的宠物领养平台。技术栈选择上,后端采用SpringBoot2提供RESTful API,前端用Vue3实现响应式界面,数据持久层使用MyBatis-Plus简化CRUD操作,MySQL8.0负责数据存储。整套系统采用前后端分离架构,实测在4核8G服务器上可支撑每秒300+的并发领养申请查询。
SpringBoot2的启动类配置了关键注解:
java复制@SpringBootApplication
@MapperScan("com.adoption.mapper")
@EnableTransactionManagement
public class AdoptionApplication {
public static void main(String[] args) {
SpringApplication.run(AdoptionApplication.class, args);
}
}
MyBatis-Plus的实体类设计特别注意了宠物特殊属性的处理:
java复制@Data
@TableName("pet_info")
public class Pet {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
@EnumValue
private PetType type; // 枚举转换
@TableField("health_status")
private String healthStatus;
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
}
采用Composition API实现的宠物筛选组件:
vue复制<script setup>
const filters = reactive({
petType: null,
ageRange: [0, 15],
isVaccinated: false
});
const { data: pets } = useFetch('/api/pets', {
query: filters,
watch: [filters]
});
</script>
关键经验:Vue3的响应式系统与SpringBoot的@RequestParam映射需要特别注意参数命名风格转换,前端camelCase和后端snake_case的自动转换需统一配置
宠物表的核心字段设计:
sql复制CREATE TABLE `pet` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`type` enum('DOG','CAT','OTHER') COLLATE utf8mb4_unicode_ci NOT NULL,
`birth_date` date DEFAULT NULL,
`adoption_status` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'AVAILABLE',
`health_records` json DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_status_type` (`adoption_status`,`type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
使用枚举实现状态流转控制:
java复制public enum AdoptionStatus {
PENDING(1) {
@Override
public AdoptionStatus nextStatus() {
return APPROVED;
}
},
APPROVED(2) {
@Override
public AdoptionStatus nextStatus() {
return COMPLETED;
}
};
// 状态校验逻辑
public void validateTransition(AdoptionStatus newStatus) {
if (newStatus != nextStatus()) {
throw new IllegalStateException("无效状态转换");
}
}
}
利用MySQL8.0的JSON字段存储动态健康数据:
java复制@TableField(typeHandler = JsonTypeHandler.class)
private List<HealthRecord> healthRecords;
// 示例查询
@Select("SELECT * FROM pet WHERE JSON_CONTAINS(health_records, '{\"vaccine\": \"rabies\"}', '$')")
List<Pet> findPetsWithRabiesVaccine();
Nginx反向代理的关键配置:
nginx复制location /api {
proxy_pass http://127.0.0.1:8080;
proxy_set_header X-Real-IP $remote_addr;
# 文件上传大小限制
client_max_body_size 20M;
}
location / {
root /var/www/adoption-frontend;
try_files $uri $uri/ /index.html;
}
使用Spring Cache抽象层配置宠物详情缓存:
java复制@Cacheable(value = "petDetail", key = "#id", unless = "#result == null")
@GetMapping("/pets/{id}")
public Pet getPetDetail(@PathVariable Long id) {
return petService.getById(id);
}
@CacheEvict(value = "petDetail", key = "#pet.id")
@PutMapping("/pets")
public void updatePet(@RequestBody Pet pet) {
petService.updateById(pet);
}
SpringBoot的CORS配置类:
java复制@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("https://your-domain.com")
.allowedMethods("*")
.allowedHeaders("*")
.allowCredentials(true)
.maxAge(3600);
}
}
需同时配置SpringBoot和Nginx:
yaml复制# application.yml
spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 20MB
基于用户画像的推荐实现:
java复制public List<Pet> recommendPets(User user) {
return petMapper.selectList(new QueryWrapper<Pet>()
.eq("type", user.getPreferredPetType())
.between("age",
user.getPreferredMinAge(),
user.getPreferredMaxAge())
.orderByDesc("create_time")
.last("LIMIT 10"));
}
使用uni-app改造现有Vue3组件:
javascript复制// 修改main.js
import { createSSRApp } from 'vue'
import App from './App.vue'
export function createApp() {
const app = createSSRApp(App)
return { app }
}
这套系统在实际部署中经历过三次重大迭代,最深刻的教训是初期低估了图片处理的需求量。后来我们引入了WebP格式自动转换和CDN加速,将图片加载时间从平均2.3秒降到了0.4秒。对于准备二次开发的同行,建议特别关注宠物健康记录的标准化设计,这是后期扩展医疗模块的基础。