聚焦“Java实现”与“多端适配”,区别于单纯的功能介绍,重点拆解系统架构、核心业务逻辑、小程序+APP对接方案,提供可直接复用的源码片段(后端核心代码、多端接口适配代码),兼顾实战性与可扩展性;既适合Java后端开发者作为实战项目学习,也适合创业团队快速复用源码,搭建属于自己的同城货运货拉拉类系统,全程贴合实际业务场景,可直接对接小程序、APP前端。

一、系统整体概述(贴合货拉拉核心场景)

本系统是一套基于Java开发的同城货运货拉拉类系统,复刻货拉拉核心业务逻辑,支持用户(货主)通过小程序/APP下单、司机通过APP接单、平台后台管理全流程,实现“货主下单→平台匹配→司机接单→货物运输→确认收货→结算评价”的闭环,同时适配多端同步,一套后端服务支撑小程序、Android APP、iOS APP三种前端形态,降低开发与维护成本。

1.1 核心技术栈(多端适配+稳定高效)

系统技术栈选型兼顾稳定性、多端适配性与易扩展性,采用业界成熟方案,后端统一对接多端前端,无需单独开发,核心技术栈如下:

  • 后端核心:SpringBoot 3.x(快速开发、简化配置,内置容器,支持多端接口统一暴露);

  • 持久层:MyBatis-Plus(简化CRUD操作,支持复杂SQL查询,适配订单、司机、货物等核心数据);

  • 数据存储:MySQL 5.7 + Redis 6.0(MySQL存储核心业务数据,Redis缓存司机在线状态、热门货运路线、用户会话);

  • 地图服务:高德地图API(实现实时定位、距离计算、路线规划、运输轨迹绘制,支撑货运核心场景);

  • 多端适配:UniApp(小程序+APP统一开发,一套代码编译多端,降低前端开发成本);

  • 鉴权安全:JWT + Redis令牌(多端统一鉴权,支持无感刷新,保障接口访问安全);

  • 部署环境:JDK 1.8+、Maven 3.6+、Docker(支持单机部署、容器化部署,适配小程序+APP线上部署需求)。

1.2 系统整体架构(多端统一后端)

系统采用前后端分离架构,后端统一提供RESTful接口,对接小程序、APP前端,架构清晰、解耦性强,便于二次开发与多端扩展,完整架构分层如下:

  1. 前端层:小程序(货主端)、Android APP(货主+司机端)、iOS APP(货主+司机端),基于UniApp开发,共享一套前端代码;

  2. 接口层(Controller):统一暴露多端通用接口,处理前端请求,返回统一响应结果,适配小程序与APP的请求格式;

  3. 业务逻辑层(Service):处理核心业务逻辑,如订单创建、司机匹配、价格计算、轨迹上报等;

  4. 数据访问层(Mapper):负责数据的增删改查,基于MyBatis-Plus实现,简化数据操作;

  5. 公共层(Common):封装统一响应、异常处理、工具类(地图工具、加密工具、订单号生成工具);

  6. 配置层(Config):统一配置数据库、Redis、地图API、JWT、多端接口适配等核心组件。

二、核心功能模块(复刻货拉拉核心业务)

系统围绕同城货运核心场景,拆解为6大核心模块,覆盖货主、司机、平台管理员全角色,支持小程序+APP多端同步使用,每个模块功能完整、可直接复用,具体如下:

2.1 货主端模块(小程序+APP通用)

核心功能:用户注册登录(手机号验证码登录,多端同步)、货物发布(填写货物类型、重量、体积、取送地址)、订单下单、预估价格查询、司机匹配查看、运输轨迹追踪、确认收货、订单评价、钱包管理(充值、支付、提现)、订单历史查询。

2.2 司机端模块(APP专属,支持小程序辅助)

核心功能:司机注册认证(身份证、驾驶证、车辆信息上传,平台审核)、在线/离线切换、接单管理(接单、拒单、取消订单)、运输轨迹上报、货物送达确认、收入统计(今日收入、总收益)、提现申请、订单历史查询、消息通知(新订单提醒、订单状态变更)。

2.3 订单模块(核心模块,多端同步)

核心功能:订单创建、订单状态流转、订单匹配(基于距离、车型匹配司机)、订单查询(按状态、时间筛选)、异常订单处理(取消、申诉)、订单详情展示(货物信息、司机信息、轨迹信息)。

订单状态流转(贴合货拉拉逻辑):待接单 → 已接单 → 已取货 → 运输中 → 已送达 → 已结算(支持待接单/已接单状态取消)。

2.4 地图与定位模块(多端适配)

核心功能:实时定位(货主取送地址定位、司机实时位置定位)、地址解析(文字地址转经纬度)、距离计算(取送地址距离,用于预估价格)、路线规划(司机运输路线)、轨迹绘制(运输全程轨迹,货主可实时查看)、附近司机推荐。

2.5 价格计算模块

核心功能:基于距离、货物重量、体积、车型,实现自动预估价格(复刻货拉拉计费逻辑),支持平台自定义计费规则(基础价、里程费、重量费、体积费),多端同步显示预估价格。

2.6 后台管理模块

核心功能:用户管理(货主、司机)、司机认证审核、订单管理(订单查询、异常处理、订单统计)、价格管理(计费规则配置)、车辆管理(司机车辆信息审核)、数据统计(订单量、营收、活跃用户、司机接单率)、权限管理(角色分配、接口权限控制)。

三、核心数据库设计(可直接导入,适配多端)

数据库设计是系统的基础,结合同城货运货拉拉场景,设计8张核心表,覆盖货主、司机、订单、车辆等全量数据,字段规范、关联清晰,添加合理索引优化查询效率,适配多端同步的数据需求,以下提供核心表结构与建表语句(可直接复制到MySQL执行,完整数据库脚本包含在源码包中)。

-- 1. 货主/用户表(多端通用,存储货主核心信息) CREATE TABLE `t_user` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID(主键)', `phone` varchar(20) NOT NULL COMMENT '手机号(唯一,登录账号)', `nickname` varchar(50) DEFAULT NULL COMMENT '用户昵称', `avatar` varchar(255) DEFAULT NULL COMMENT '用户头像', `id_card` varchar(20) DEFAULT NULL COMMENT '身份证号(实名认证)', `balance` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '用户余额', `user_type` tinyint NOT NULL COMMENT '用户类型:1-货主,2-司机', `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态:1-正常,0-禁用', `create_time` datetime NOT NULL COMMENT '注册时间', `update_time` datetime NOT NULL COMMENT '更新时间', PRIMARY KEY (`id`), UNIQUE KEY `idx_phone` (`phone`) COMMENT '手机号唯一索引' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统用户表'; -- 2. 司机信息表(关联用户表) CREATE TABLE `t_driver` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '司机ID(主键)', `user_id` bigint NOT NULL COMMENT '关联用户ID', `name` varchar(50) NOT NULL COMMENT '司机姓名', `license` varchar(50) NOT NULL COMMENT '驾驶证号', `car_type` tinyint NOT NULL COMMENT '车型:1-小面,2-中面,3-小卡,4-大卡', `license_plate` varchar(20) NOT NULL COMMENT '车牌号', `car_load` decimal(5,2) NOT NULL COMMENT '车辆载重(吨)', `car_volume` decimal(5,2) NOT NULL COMMENT '车辆容积(立方米)', `status` tinyint NOT NULL DEFAULT 0 COMMENT '状态:0-待审核,1-空闲,2-忙碌,3-禁用', `balance` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '可提现余额', PRIMARY KEY (`id`), UNIQUE KEY `idx_user_id` (`user_id`), UNIQUE KEY `idx_license_plate` (`license_plate`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='司机信息表'; -- 3. 货运订单表(核心表,多端同步) CREATE TABLE `t_cargo_order` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '订单ID(主键)', `order_no` varchar(32) NOT NULL COMMENT '订单编号(唯一)', `user_id` bigint NOT NULL COMMENT '货主ID', `driver_id` bigint DEFAULT NULL COMMENT '接单司机ID', `cargo_type` varchar(30) NOT NULL COMMENT '货物类型(如:家具、家电、小件)', `cargo_weight` decimal(5,2) NOT NULL COMMENT '货物重量(吨)', `cargo_volume` decimal(5,2) NOT NULL COMMENT '货物容积(立方米)', `start_addr` varchar(255) NOT NULL COMMENT '取货地址', `end_addr` varchar(255) NOT NULL COMMENT '送货地址', `start_lng` decimal(12,8) DEFAULT NULL COMMENT '取货经度', `start_lat` decimal(12,8) DEFAULT NULL COMMENT '取货纬度', `end_lng` decimal(12,8) DEFAULT NULL COMMENT '送货经度', `end_lat` decimal(12,8) DEFAULT NULL COMMENT '送货纬度', `distance` decimal(8,2) DEFAULT NULL COMMENT '预估距离(km)', `amount` decimal(10,2) NOT NULL COMMENT '订单总金额', `order_status` tinyint NOT NULL COMMENT '订单状态:0-待接单,1-已接单,2-已取货,3-运输中,4-已送达,5-已取消', `create_time` datetime NOT NULL COMMENT '创建时间', `update_time` datetime NOT NULL COMMENT '更新时间', PRIMARY KEY (`id`), UNIQUE KEY `idx_order_no` (`order_no`), KEY `idx_user_id` (`user_id`), KEY `idx_driver_id` (`driver_id`), KEY `idx_order_status` (`order_status`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='同城货运订单表';

四、核心源码片段(多端适配,可直接复用)

本节展示系统核心业务(订单创建、司机接单、多端接口适配)的精简源码片段,覆盖枚举、Service、Controller层,代码规范、逻辑清晰,适配小程序+APP多端请求,无需冗余修改即可融入系统,避免过多代码堆砌,重点突出实用性与多端适配性。

4.1 核心枚举(订单状态、车型)

/** * 订单状态枚举(贴合货拉拉逻辑) */ public enum OrderStatusEnum { WAIT_RECEIVE(0, "待接单"), RECEIVED(1, "已接单"), PICKED_UP(2, "已取货"), TRANSPORTING(3, "运输中"), DELIVERED(4, "已送达"), CANCELLED(5, "已取消"); private final Integer code; private final String desc; OrderStatusEnum(Integer code, String desc) { this.code = code; this.desc = desc; } // 根据状态码获取枚举,用于订单状态判断(多端通用) public static OrderStatusEnum getByCode(Integer code) { for (OrderStatusEnum status : values()) { if (status.code.equals(code)) { return status; } } throw new IllegalArgumentException("无效订单状态:" + code); } public Integer getCode() { return code; } public String getDesc() { return desc; } } /** * 车型枚举(适配货拉拉常见车型) */ public enum CarTypeEnum { SMALL_VAN(1, "小面", new BigDecimal("0.5"), new BigDecimal("2.0")), MEDIUM_VAN(2, "中面", new BigDecimal("1.0"), new BigDecimal("4.0")), SMALL_TRUCK(3, "小卡", new BigDecimal("2.0"), new BigDecimal("8.0")), LARGE_TRUCK(4, "大卡", new BigDecimal("5.0"), new BigDecimal("20.0")); private final Integer code; private final String desc; private final BigDecimal maxWeight; // 最大载重(吨) private final BigDecimal maxVolume; // 最大容积(立方米) CarTypeEnum(Integer code, String desc, BigDecimal maxWeight, BigDecimal maxVolume) { this.code = code; this.desc = desc; this.maxWeight = maxWeight; this.maxVolume = maxVolume; } public Integer getCode() { return code; } public String getDesc() { return desc; } public BigDecimal getMaxWeight() { return maxWeight; } public BigDecimal getMaxVolume() { return maxVolume; } }

4.2 订单创建核心逻辑(多端通用,Service层)

统一处理小程序、APP货主端的订单创建请求,自动计算距离、预估价格,匹配合适车型的司机,核心代码如下:

/** * 订单服务实现类(核心业务逻辑,多端通用) */ @Service @Slf4j public class CargoOrderServiceImpl implements CargoOrderService { @Autowired private CargoOrderMapper orderMapper; @Autowired private AmapUtil amapUtil; // 地图工具类(封装高德API) @Autowired private DriverMapper driverMapper; /** * 创建货运订单(小程序+APP货主端通用) */ @Override public String createOrder(CargoOrderDTO dto) { try { // 1. 地址解析:将文字地址转为经纬度(前端未传时调用,多端适配) if (dto.getStartLng() == null || dto.getStartLat() == null) { Map<String, Object> startGeo = amapUtil.getGeoByAddress(dto.getStartAddr()); dto.setStartLng(new BigDecimal(startGeo.get("lng").toString())); dto.setStartLat(new BigDecimal(startGeo.get("lat").toString())); } if (dto.getEndLng() == null || dto.getEndLat() == null) { Map<String, Object> endGeo = amapUtil.getGeoByAddress(dto.getEndAddr()); dto.setEndLng(new BigDecimal(endGeo.get("lng").toString())); dto.setEndLat(new BigDecimal(endGeo.get("lat").toString())); } // 2. 计算预估距离(km) double distance = amapUtil.calculateDistance( dto.getStartLng().doubleValue(), dto.getStartLat().doubleValue(), dto.getEndLng().doubleValue(), dto.getEndLat().doubleValue() ); // 3. 校验货物与车型匹配(根据货物重量、体积匹配车型) CarTypeEnum carType = CarTypeEnum.getByCode(dto.getCarType()); if (dto.getCargoWeight().compareTo(carType.getMaxWeight()) > 0) { throw new BusinessException("货物重量超出所选车型最大载重"); } if (dto.getCargoVolume().compareTo(carType.getMaxVolume()) > 0) { throw new BusinessException("货物体积超出所选车型最大容积"); } // 4. 计算预估价格(复刻货拉拉计费逻辑:基础价 + 里程费 + 重量费) BigDecimal amount = calculateOrderAmount(carType, distance, dto.getCargoWeight()); // 5. 构建订单实体,初始化状态为待接单 CargoOrder order = new CargoOrder(); order.setOrderNo(generateOrderNo()); // 生成唯一订单号 order.setUserId(dto.getUserId()); order.setCargoType(dto.getCargoType()); order.setCargoWeight(dto.getCargoWeight()); order.setCargoVolume(dto.getCargoVolume()); order.setStartAddr(dto.getStartAddr()); order.setEndAddr(dto.getEndAddr()); order.setStartLng(dto.getStartLng()); order.setStartLat(dto.getStartLat()); order.setEndLng(dto.getEndLng()); order.setEndLat(dto.getEndLat()); order.setDistance(new BigDecimal(distance)); order.setAmount(amount); order.setOrderStatus(OrderStatusEnum.WAIT_RECEIVE.getCode()); order.setCreateTime(new Date()); order.setUpdateTime(new Date()); // 6. 保存订单 orderMapper.insert(order); // 7. 异步匹配附近空闲司机(多端同步通知) asyncMatchDriver(order); log.info("货主{}创建货运订单成功,订单号:{}", dto.getUserId(), order.getOrderNo()); return order.getOrderNo(); } catch (Exception e) { log.error("创建货运订单失败", e); throw new BusinessException("订单创建失败,请重试"); } } /** * 生成唯一订单号(时间戳 + 6位随机数,多端通用,避免重复) */ private String generateOrderNo() { return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + RandomUtil.randomNumbers(6); } /** * 订单价格计算(贴合货拉拉计费规则) */ private BigDecimal calculateOrderAmount(CarTypeEnum carType, double distance, BigDecimal cargoWeight) { BigDecimal basePrice = new BigDecimal("30.00"); // 基础起步价(不同车型可调整) BigDecimal unitPrice = new BigDecimal("3.00"); // 每公里里程费 BigDecimal weightPrice = new BigDecimal("5.00"); // 每吨重量费 // 不同车型基础价不同 if (CarTypeEnum.MEDIUM_VAN.getCode().equals(carType.getCode())) { basePrice = new BigDecimal("50.00"); } else if (CarTypeEnum.SMALL_TRUCK.getCode().equals(carType.getCode())) { basePrice = new BigDecimal("80.00"); } else if (CarTypeEnum.LARGE_TRUCK.getCode().equals(carType.getCode())) { basePrice = new BigDecimal("150.00"); } // 总价格 = 基础价 + 里程费 + 重量费 BigDecimal distancePrice = unitPrice.multiply(new BigDecimal(distance)); BigDecimal totalWeightPrice = weightPrice.multiply(cargoWeight); return basePrice.add(distancePrice).add(totalWeightPrice); } /** * 异步匹配附近空闲司机(多端同步通知司机) */ @Async("asyncPool") public void asyncMatchDriver(CargoOrder order) { // 1. 查询附近空闲、车型匹配的司机(根据经纬度筛选) List<Driver> driverList = driverMapper.selectNearbyDriver( order.getStartLng(), order.getStartLat(), order.getCarType() ); // 2. 给司机发送新订单通知(APP推送、小程序订阅消息) if (CollectionUtils.isNotEmpty(driverList)) { for (Driver driver : driverList) { messageService.sendNewOrderNotice(driver.getUserId(), order.getOrderNo()); } } } }

4.3 多端通用接口(Controller层,适配小程序+APP)

统一提供接口,适配小程序、APP的请求格式,支持货主下单、司机接单,核心代码如下:

/** * 订单控制器(多端通用接口,适配小程序+APP) */ @RestController @RequestMapping("/api/cargo/order") public class CargoOrderController { @Autowired private CargoOrderService orderService; /** * 货主创建订单(小程序+APP通用接口) */ @PostMapping("/create") public Result<String> createOrder(@RequestBody @Valid CargoOrderDTO dto, @RequestHeader("userId") Long userId) { dto.setUserId(userId); String orderNo = orderService.createOrder(dto); return Result.success(orderNo, "订单创建成功,等待司机接单"); } /** * 司机接单接口(APP司机端专用,小程序辅助查看) */ @PostMapping("/receive") public Result<Boolean> receiveOrder(@RequestParam String orderNo, @RequestHeader("userId") Long userId) { // 校验司机身份(确保是司机账号) boolean isDriver = userService.checkDriverIdentity(userId); if (!isDriver) { return Result.fail("非司机账号,无法接单"); } boolean result = orderService.driverReceiveOrder(orderNo, userId); return result ? Result.success(true, "接单成功,前往取货") : Result.fail("接单失败,订单状态异常"); } /** * 订单轨迹查询(多端通用,货主查看运输轨迹) */ @GetMapping("/track") public Result<List<TrackVO>> getOrderTrack(@RequestParam String orderNo) { List<TrackVO> trackList = orderService.getOrderTrack(orderNo); return Result.success(trackList); } }

4.4 多端适配关键配置(小程序+APP统一对接)

通过配置统一的接口前缀、跨域设置,实现小程序+APP与后端的无缝对接,核心配置如下:

/** * 跨域配置(适配小程序、APP跨域请求) */ @Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**") // 允许小程序、APP的域名(实际项目中替换为真实域名) .allowedOrigins("https://xxx.weixin.qq.com", "http://xxx.app.com") .allowedMethods("GET", "POST", "PUT", "DELETE") .allowedHeaders("*") .allowCredentials(true) .maxAge(3600); } } /** * JWT配置(多端统一鉴权,小程序、APP共用一套令牌机制) */ @Configuration public class JwtConfig { @Value("${jwt.secret}") private String secret; @Value("${jwt.expiration}") private Long expiration; // 生成令牌(多端通用) public String generateToken(Long userId) { Date now = new Date(); Date expireDate = new Date(now.getTime() + expiration * 1000); return Jwts.builder() .setSubject(userId.toString()) .setIssuedAt(now) .setExpiration(expireDate) .signWith(SignatureAlgorithm.HS512, secret) .compact(); } // 校验令牌(多端通用) public boolean validateToken(String token) { try { Jwts.parser().setSigningKey(secret).parseClaimsJws(token); return true; } catch (Exception e) { return false; } } }

五、小程序+APP多端部署与源码使用指南

本系统提供完整的小程序+APP前端对接代码、后端源码,下载后即可快速部署、测试,无需复杂配置,适合新手操作,核心部署与使用步骤如下:

5.1 部署前置准备

  1. 环境准备:安装JDK 1.8+、Maven 3.6+、MySQL 8.0+、Redis 6.0+、Docker(可选)、HBuilderX(前端编译);

  2. 源码准备:下载完整源码包(包含后端代码、前端小程序+APP代码、数据库脚本);

  3. 数据库准备:创建数据库(如cargo_system),执行源码包中的完整数据库脚本(含初始化数据);

  4. 配置修改:修改后端application.yml文件,配置数据库连接、Redis连接、高德地图API密钥、跨域域名;修改前端代码中的接口地址,对接后端服务。

5.2 多端部署步骤

  1. 后端部署:在IDEA中执行Maven打包命令(mvn clean package -DskipTests),生成Jar包,上传至服务器执行后台运行命令,或使用Docker一键部署;

  2. 小程序部署:使用HBuilderX打开前端小程序代码,配置小程序AppID,编译后上传至微信公众平台,审核通过后即可使用;

  3. APP部署:使用HBuilderX打开前端代码,选择Android/iOS打包,生成安装包,即可安装使用;

  4. 接口测试:通过Postman测试核心接口,确保小程序、APP与后端对接正常,核心功能可正常使用。

5.3 源码二次开发建议

源码架构清晰、代码规范,支持灵活二次开发,可根据实际业务需求扩展以下功能,适配不同运营场景:

  • 营销模块:新增优惠券、满减活动、邀请有礼,提升用户活跃度;

  • 支付扩展:对接微信支付、支付宝支付,实现在线支付、退款、平台分账;

  • 消息扩展:集成语音通知、短信通知,订单状态变更时及时提醒货主与司机;

  • 功能扩展:新增货物保险、预约下单、拼单运输等功能,丰富平台服务。

六、总结与源码获取

本文基于Java技术栈,完整分享了同城货运货拉拉系统的开发思路、核心模块、多端适配方案,重点拆解了订单创建、司机接单等核心业务的源码实现,适配小程序+APP多端部署需求,提供的源码可直接复用、易二次开发

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐