基于微服务的宠物商城社交托运购物平台开发实战
基于微服务的宠物商城社交托运购物平台开发实战
随着宠物经济持续升温,宠物主对“购物+社交+托运”一体化服务的需求日益增长。一个既能购买宠物食品用品、又能找宠友交流、还能预约托运服务的平台,已成为行业刚需。本文结合Spring Boot微服务架构与UniApp跨端技术,完整讲解宠物商城社交托运购物平台从业务建模到落地的技术方案。
一、整体架构设计与技术选型
1.1 业务模块划分
宠物商城社交托运购物平台的核心业务可拆解为四个独立域:
- 商城域:商品管理、购物车、订单、支付、库存
- 社交域:宠物动态发布、评论点赞、关注、圈子群组
- 托运域:托运需求发布、骑手/司机抢单、转运跟踪、费用结算
- 用户域:用户注册登录、宠物档案、地址管理、积分体系
1.2 技术栈选型
| 层级 | 技术选型 |
|---|---|
| 服务端框架 | Spring Boot 2.7 + MyBatis-Plus |
| 服务注册与发现 | Nacos(或Eureka) |
| 网关层 | Spring Cloud Gateway |
| 数据库 | MySQL 8.0 + Redis 缓存 |
| 消息队列 | RabbitMQ(处理订单、推送通知) |
| 用户端 | UniApp(Vue 3语法,兼容H5/小程序/App) |
| 管理后台 | Vue 3 + Element Plus |
| 骑手/司机端 | UniApp独立分包 |
1.3 数据库核心ER设计
以托运模块为例,核心表结构如下:
-- 托运订单主表
CREATE TABLE `pet_transport_order` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`order_no` varchar(32) DEFAULT NULL COMMENT '订单编号',
`user_id` bigint(20) DEFAULT NULL,
`pet_id` bigint(20) DEFAULT NULL COMMENT '关联宠物档案',
`start_address` varchar(255) DEFAULT NULL,
`end_address` varchar(255) DEFAULT NULL,
`transport_type` tinyint(1) DEFAULT '0' COMMENT '0:同城 1:跨城',
`order_status` tinyint(1) DEFAULT '0' COMMENT '0:待接单 1:已接单 2:运输中 3:已完成',
`driver_id` bigint(20) DEFAULT NULL,
`create_time` datetime DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 宠物档案表
CREATE TABLE `pet_profile` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) DEFAULT NULL,
`pet_name` varchar(50) DEFAULT NULL,
`pet_type` varchar(20) DEFAULT NULL COMMENT 'dog/cat/other',
`breed` varchar(50) DEFAULT NULL,
`weight` decimal(5,2) DEFAULT NULL,
`vaccinated` tinyint(1) DEFAULT '0',
`photo_url` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
社交动态表、商城商品表的设计遵循类似范式,所有关联ID均建立索引,便于微服务间跨库查询时使用ID映射。
二、商城与社交模块的微服务实现
2.1 商城服务(pet-mall-service)
使用Spring Boot + MyBatis-Plus构建,对外暴露RESTful接口,通过Feign与其他服务通信。
商品搜索与库存扣减采用Redis缓存热点数据:
@Service
public class ProductService {
@Autowired
private StringRedisTemplate redisTemplate;
// 缓存商品基本信息,key = product:detail:{id}
public ProductVO getProductDetail(Long productId) {
String cacheKey = "product:detail:" + productId;
String cacheValue = redisTemplate.opsForValue().get(cacheKey);
if (StringUtils.isNotBlank(cacheValue)) {
return JSON.parseObject(cacheValue, ProductVO.class);
}
Product product = productMapper.selectById(productId);
ProductVO vo = convertToVO(product);
redisTemplate.opsForValue().set(cacheKey, JSON.toJSONString(vo), 30, TimeUnit.MINUTES);
return vo;
}
// 下单时基于Redis Lua脚本实现原子扣减库存
public boolean deductStock(Long productId, Integer count) {
String luaScript =
"local stock = redis.call('get', KEYS[1]) " +
"if stock and tonumber(stock) >= tonumber(ARGV[1]) then " +
" redis.call('decrby', KEYS[1], ARGV[1]) " +
" return 1 " +
"else " +
" return 0 " +
"end";
Long result = redisTemplate.execute(
new DefaultRedisScript<>(luaScript, Long.class),
Collections.singletonList("product:stock:" + productId),
count.toString()
);
return Long.valueOf(1).equals(result);
}
}
2.2 社交服务(pet-social-service)
宠物社交区别于通用社交,核心在于“以宠会友”。动态发布时需携带宠物标签,系统通过内容推荐算法推送同城或同品种内容。
动态Feed流设计方案:
采用“拉模式”与“推模式”结合:普通用户关注较少时使用推模式,将动态写入粉丝收件箱;大V用户使用拉模式,粉丝动态实时拉取。
// 推模式实现:用户发布动态后,写入粉丝的收件箱
public void publishFeed(Feed feed) {
feedMapper.insert(feed);
// 获取该用户的粉丝ID列表(分页处理)
List<Long> followerIds = userRelationMapper.getFollowerIds(feed.getUserId());
// 批量写入Redis zset,score使用时间戳
for (Long followerId : followerIds) {
String key = "inbox:" + followerId;
redisTemplate.opsForZSet().add(key, feed.getId().toString(), System.currentTimeMillis());
// 控制收件箱长度,超过1000条时裁剪
redisTemplate.opsForZSet().removeRangeByRank(key, 0, -1001);
}
}
2.3 托运服务与骑手端调度
托运模块借鉴同城配送与货运系统的实践经验,设计为独立微服务(pet-transport-service)。骑手/司机端基于UniApp开发,与管理后台共用一套接口。
抢单池实现方案:
新托运订单产生后,通过RabbitMQ广播到所有在线骑手端,骑手端在5秒内点击“抢单”即完成接单。
// 订单消息推送(生产者)
@RabbitListener(queues = "transport.order.new")
public void handleNewOrder(TransportOrder order) {
// 推送到骑手端WebSocket或通过第三方推送服务
pushService.pushToDrivers("new_order", order);
}
// 抢单处理(消费者,使用Redis分布式锁防止超抢)
public boolean grabOrder(Long orderId, Long driverId) {
String lockKey = "transport:grab:" + orderId;
Boolean locked = redisTemplate.opsForValue().setIfAbsent(lockKey, driverId.toString(), 5, TimeUnit.SECONDS);
if (Boolean.TRUE.equals(locked)) {
// 更新订单driver_id,状态改为已接单
transportOrderMapper.updateDriver(orderId, driverId);
return true;
}
return false;
}
托运费用计算采用动态计价策略:起步价 + 里程费 + 宠物类型附加费(大型犬加价),通过策略模式实现灵活扩展。
三、跨端统一与打印对接实战
3.1 UniApp跨端兼容技巧
用户端、骑手端和管理后台均基于UniApp开发,通过条件编译处理平台差异:
// 仅在小程序中调起蓝牙打印
// #ifdef MP-WEIXIN
.openBluetoothAdapter({
success() {
console.log('蓝牙适配器初始化成功');
}
});
// #endif
// 仅在H5中地图导航
// #ifdef H5
window.open(`https://uri.amap.com/navigation?from=${startLng},${startLat}&to=${endLng},${endLat}`);
// #endif
宠物商城社交托运购物平台的用户端包含三个Tab:首页(商城推荐+社交动态)、商城分类、托运下单、个人中心。其中托运下单页需要调用地图SDK获取位置,同时展示宠物档案选择器。
3.2 小票打印机对接
商城订单和托运订单完成时,后台自动推送打印指令。系统对接飞鹅打印机(基于HTTP API)与易联云打印机(基于OAuth2.0)。
// 飞鹅打印机对接示例
public void printOrder(TransportOrder order) {
String content = buildPrintContent(order);
String reqParam = String.format(
"user=%s&stime=%d&sig=%s&apiname=Open_printMsg&sn=%s&content=%s×=1",
FEI_E_USER, System.currentTimeMillis() / 1000,
generateSign(), ORDER_PRINTER_SN,
URLEncoder.encode(content, "UTF-8")
);
// 发送HTTP POST请求
String result = HttpUtil.post(FEI_E_API_URL, reqParam);
// 解析返回码判断是否成功
}
打印内容模板包含:宠物托运单号、起始地-目的地、宠物品种、重量、特殊备注(“请携带饮水”等)。商家端也可在后台独立配置打印模板。
3.3 微服务网关与统一鉴权
使用Spring Cloud Gateway作为统一入口,集成JWT Token鉴权:
spring:
cloud:
gateway:
routes:
- id: pet-mall
uri: lb://pet-mall-service
predicates:
- Path=/api/mall/**
- id: pet-social
uri: lb://pet-social-service
predicates:
- Path=/api/social/**
- id: pet-transport
uri: lb://pet-transport-service
predicates:
- Path=/api/transport/**
用户端调用任何业务接口前,需在请求头携带Authorization: Bearer {token},网关统一校验。登录注册模块使用BCrypt加密密码,并集成短信验证码(阿里云/腾讯云 SDK)。
四、FAQ:宠物商城社交托运购物平台常见技术问题
Q1:宠物档案数据需要与托运模块实时同步吗?
建议采用“终一致性”策略。用户新增宠物或更新疫苗接种信息后,通过MQ消息通知托运服务更新缓存。不要求强一致,因为托运下单时系统会拉取实时档案。
Q2:社交动态的图片和视频如何存储与管理?
推荐使用阿里云OSS或腾讯云COS。用户端上传时先请求后端获取临时上传凭证(STS),直接上传到对象存储,避免应用服务器带宽消耗。系统仅存储文件URL,动态加载时使用CDN加速。
Q3:同城宠物托运如何计算配送距离与费用?
前端基于地图SDK(高德/腾讯)获取起点和终点经纬度,调用后端计价接口。后端使用高德地图API的驾车路径规划接口计算实际里程,再根据阶梯计费规则得出费用。起步价、每公里单价和宠物附加费可在管理后台动态配置。
Q4:多商家入驻场景下,商家如何自主管理宠物商品?
为每个商家分配独立的管理后台账号,商家可上架/下架商品、配置库存、查看订单。平台方在后台设置抽佣比例,订单结算时自动计算平台分成。商品数据隔离通过shop_id字段实现,查询时增加数据权限过滤。
Q5:系统如何保证平台内敏感内容合规?
宠物社交动态和托运备注需接入内容安全审核服务(阿里云内容安全或腾讯云天御),在用户发布时同步调用检测接口。检测结果为“违规”的内容自动屏蔽并通知管理员人工复核。宠物托运还需校验宠物检疫证明图片的清晰度与有效性。
以上是宠物商城社交托运购物平台从微服务拆分、核心业务实现到跨端部署的完整开发实践。技术方案融合了同城配送、社交Feed流、商城库存管理等多个成熟系统的设计经验,开发者可根据实际业务场景灵活裁剪或扩展。
更多推荐




所有评论(0)