以下是一个前后端分离开发的Java跑腿系统实战方案,涵盖用户端、骑手端和后台管理端三端开发,采用Spring Boot + Vue.js/Uni-app + MySQL技术栈,实现高效、可扩展的同城跑腿服务。
一、系统架构设计
1. 技术选型
- 后端:Spring Boot 2.7 + Spring Security(认证授权) + MyBatis-Plus(ORM) + Redis(缓存) + RabbitMQ(消息队列)
- 前端 :
- 用户端/骑手端:Uni-app(跨平台小程序/APP)
- 后台管理端:Vue.js 3 + Element Plus(PC端管理后台)
- 数据库:MySQL 8.0(主从复制)
- 部署:Docker + Nginx(负载均衡) + Jenkins(CI/CD)
2. 架构图
`用户端/骑手端(Uni-app) ↔ Nginx ↔ Spring Boot集群 ↔ MySQL主从
↑ ↓
Redis缓存 RabbitMQ消息队列
↑
后台管理端(Vue.js)
`
二、核心功能模块
1. 用户端功能
- 注册/登录:手机号验证码登录、微信授权登录
- 跑腿下单:选择服务类型(代购、取送件等)、填写地址、支付预付款
- 订单跟踪:实时查看骑手位置、订单状态变更通知
- 评价系统:对骑手服务评分和文字评价
- 历史订单:查看已完成/取消的订单记录
2. 骑手端功能
- 注册/认证:上传身份证、健康证,后台审核
- 接单大厅:按距离/报酬筛选订单,抢单模式
- 导航功能:集成高德/腾讯地图API,规划最优路线
- 收入统计:查看当日/历史收入,提现申请
- 在线状态:设置接单/休息状态
3. 后台管理端功能
- 用户管理:冻结/解封用户账号
- 骑手管理:审核骑手资质、查看骑手评分
- 订单管理:异常订单处理、强制取消订单
- 数据统计:订单量、收入、用户增长趋势图表
- 系统配置:服务类型、计价规则、通知模板设置
三、数据库设计(关键表)
1. 用户表(t_user)
sql
``CREATE TABLE `t_user` (
`id` BIGINT PRIMARY KEY AUTO_INCREMENT,
`phone` VARCHAR(20) NOT NULL UNIQUE,
`password` VARCHAR(100), -- 加密存储
`nickname` VARCHAR(50),
`avatar` VARCHAR(255),
`status` TINYINT DEFAULT 1 COMMENT '1-正常 0-冻结',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP
);
``
2. 骑手表(t_runner)
sql
``CREATE TABLE `t_runner` (
`id` BIGINT PRIMARY KEY AUTO_INCREMENT,
`user_id` BIGINT NOT NULL UNIQUE COMMENT '关联用户表',
`real_name` VARCHAR(50) NOT NULL,
`id_card` VARCHAR(18) NOT NULL UNIQUE,
`health_cert` VARCHAR(255),
`status` TINYINT DEFAULT 0 COMMENT '0-待审核 1-审核通过 2-拒绝',
`online_status` TINYINT DEFAULT 0 COMMENT '0-离线 1-在线 2-接单中',
`avg_score` DECIMAL(3,1) DEFAULT 5.0,
`audit_opinion` VARCHAR(255) COMMENT '审核意见'
);
``
3. 订单表(t_order)
sql
``CREATE TABLE `t_order` (
`id` BIGINT PRIMARY KEY AUTO_INCREMENT,
`order_no` VARCHAR(32) NOT NULL UNIQUE COMMENT '订单编号',
`user_id` BIGINT NOT NULL COMMENT '下单用户',
`runner_id` BIGINT COMMENT '接单骑手',
`service_type` TINYINT NOT NULL COMMENT '1-代购 2-取件 3-送件',
`from_address` VARCHAR(255) NOT NULL,
`to_address` VARCHAR(255) NOT NULL,
`pre_fee` DECIMAL(10,2) NOT NULL COMMENT '预付款',
`actual_fee` DECIMAL(10,2) COMMENT '实际费用',
`status` TINYINT DEFAULT 0 COMMENT '0-待接单 1-已接单 2-进行中 3-已完成 4-已取消',
`cancel_reason` VARCHAR(255) COMMENT '取消原因',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP
);
``
四、关键代码实现
1. 后端接口示例(Spring Boot)
订单创建接口:
java
`@RestController
@RequestMapping("/api/order")
public class OrderController {
@Autowired
private OrderService orderService;
@PostMapping("/create")
public Result<String> createOrder(@RequestBody @Valid OrderCreateDTO dto,
@AuthenticationPrincipal UserDetails userDetails) {
Long userId = Long.parseLong(userDetails.getUsername());
String orderNo = orderService.createOrder(userId, dto);
return Result.success("订单创建成功", orderNo);
}
}
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Override
@Transactional
public String createOrder(Long userId, OrderCreateDTO dto) {
// 生成订单号
String orderNo = "ORD" + System.currentTimeMillis();
// 保存订单
Order order = new Order();
order.setOrderNo(orderNo);
order.setUserId(userId);
order.setServiceType(dto.getServiceType());
// 其他字段设置...
orderMapper.insert(order);
// 预扣款(Redis分布式锁防止超卖)
String lockKey = "LOCK:ORDER:" + orderNo;
try {
Boolean locked = redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 10, TimeUnit.SECONDS);
if (Boolean.TRUE.equals(locked)) {
// 调用支付服务预扣款(伪代码)
paymentService.prePay(userId, orderNo, dto.getPreFee());
}
} finally {
redisTemplate.delete(lockKey);
}
return orderNo;
}
}
`
2. 前端示例(Uni-app)
骑手接单页面:
javascript
``// pages/runner/order-list.vue
<template>
<view>
<van-swipe-cell v-for="order in orderList" :key="order.id">
<van-card
:title="`${getServiceType(order.serviceType)} · ¥${order.preFee}`"
:desc="`${order.fromAddress} → ${order.toAddress}`"
thumb="/static/order.png"
/>
<template #right>
<van-button square type="primary" @click="acceptOrder(order)">接单</van-button>
</template>
</van-swipe-cell>
</view>
</template>
<script>
export default {
data() {
return {
orderList: []
};
},
onLoad() {
this.fetchOrders();
},
methods: {
async fetchOrders() {
const res = await uni.request({
url: 'https://api.example.com/api/order/available',
method: 'GET',
header: { 'Authorization': `Bearer ${uni.getStorageSync('token')}` }
});
this.orderList = res.data.data;
},
acceptOrder(order) {
uni.showLoading({ title: '接单中...' });
uni.request({
url: 'https://api.example.com/api/order/accept',
method: 'POST',
data: { orderId: order.id },
header: { 'Authorization': `Bearer ${uni.getStorageSync('token')}` },
success: () => {
uni.hideLoading();
uni.showToast({ title: '接单成功' });
this.fetchOrders();
}
});
}
}
};
</script>
``
五、部署与优化
1. 部署方案
- 后端:Docker打包为镜像,通过Kubernetes部署多节点
- 数据库:MySQL主从复制,读写分离
- 缓存:Redis集群部署,避免单点故障
- 前端:Uni-app编译为微信小程序和H5,Vue.js打包为静态文件部署至Nginx
2. 性能优化
- 接口限流:使用Guava RateLimiter防止恶意请求
- 数据缓存:热点数据(如骑手位置)使用Redis缓存
- 异步处理:订单状态变更、通知发送等使用RabbitMQ异步处理
- 数据库优化:合理设计索引,避免全表扫描
六、扩展功能建议
- 智能派单算法:基于骑手位置、订单距离、评分等维度自动派单
- 保险服务:集成第三方保险接口,为每笔订单提供保障
- 拼单功能:支持多个用户合并订单,降低配送成本
- AI客服:接入ChatGPT API实现智能客服答疑
此方案涵盖了从需求分析到部署上线的完整流程,可根据实际需求调整技术栈和功能模块。开发过程中建议使用Swagger生成API文档,Postman进行接口测试,SonarQube进行代码质量检查。