JAVA代泊车接机送机服务代客泊车系统源码支持小程序+APP+H5

JAVA代泊车接机送机服务代客泊车系统源码:数字化革新出行服务生态

在当今都市生活节奏不断加快的背景下,随着汽车保有量的持续增长和出行需求的日益多元化,传统停车服务和机场接送服务正面临前所未有的挑战。城市停车位紧张、机场接送效率低下、服务标准不统一等行业痛点严重制约了出行服务行业的发展。JAVA代泊车接机送机服务代客泊车系统源码应运而生,以其创新的商业模式和全面的技术架构,为出行服务行业带来革命性变革。这套JAVA代泊车接机送机服务代客泊车系统源码整合了小程序、APP和H5等多端入口,通过springboot+mybatisplus+mysql构建稳定高效的后台服务,uniapp实现用户端跨平台开发,vue+elementUi打造专业管理后台,彻底解决了传统代泊车服务中信息不透明、服务效率低、安全无保障以及机场接送服务中调度不及时、路线不优化、费用不透明等核心问题。用户可以通过JAVA代泊车接机送机服务代客泊车系统源码随时随地预约专业代泊车服务、安排机场接送车辆,系统智能匹配服务人员与用户需求,实时追踪车辆位置,确保服务过程安全可靠。这种JAVA代泊车接机送机服务代客泊车系统源码真正实现了出行服务行业的数字化转型,构建起连接车主、代驾员、停车场、机场服务方的完整生态体系,市场前景广阔,发展潜力巨大。

系统架构设计与核心技术优势

本JAVA代泊车接机送机服务代客泊车系统源码采用前后端分离的现代化架构,后端基于SpringBoot框架提供稳定的RESTful API接口,前端通过uniapp实现一次开发多端部署,管理端使用Vue.js配合ElementUI组件库。这种JAVA代泊车接机送机服务代客泊车系统源码架构确保了系统的高性能、高可用性和易维护性。

核心架构代码示例:

复制代码
// SpringBoot主启动类配置
@SpringBootApplication
@MapperScan("com.valet.system.mapper")
@EnableScheduling
@EnableAsync
@EnableCaching
public class ValetSystemApplication {
    public static void main(String[] args) {
        SpringApplication.run(ValetSystemApplication.class, args);
    }
}

// MybatisPlus配置类
@Configuration
@EnableTransactionManagement
public class MybatisPlusConfig {
    
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 分页插件
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        // 乐观锁插件
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        // 动态表名插件
        interceptor.addInnerInterceptor(new DynamicTableNameInnerInterceptor());
        return interceptor;
    }
}

// Redis缓存配置
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
    
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        
        Jackson2JsonRedisSerializer<Object> serializer = 
            new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper mapper = new ObjectMapper();
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        mapper.activateDefaultTyping(LazyCollectionDefaultingTyping, 
            ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(mapper);
        
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(serializer);
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(serializer);
        template.afterPropertiesSet();
        
        return template;
    }
}

// 高德地图服务配置
@Configuration
public class MapServiceConfig {
    
    @Value("${amap.key}")
    private String amapKey;
    
    @Bean
    public GeoService geoService() {
        return new GeoService(amapKey);
    }
    
    @Bean
    public DirectionService directionService() {
        return new DirectionService(amapKey);
    }
}
数据库设计与数据持久层实现

JAVA代泊车接机送机服务代客泊车系统源码采用MySQL数据库,通过精心设计的表结构确保数据一致性和完整性。核心表包括代泊车订单表、服务人员表、停车场信息表、机场接送订单表等。

实体类和Mapper层代码示例:

复制代码
// 代泊车订单实体类
@Data
@TableName("valet_order")
@ApiModel(value = "ValetOrder对象", description = "代泊车订单表")
public class ValetOrder {
    @TableId(type = IdType.ASSIGN_ID)
    @ApiModelProperty("订单ID")
    private Long orderId;
    
    @ApiModelProperty("订单编号")
    private String orderNo;
    
    @ApiModelProperty("用户ID")
    private Long userId;
    
    @ApiModelProperty("服务人员ID")
    private Long valetId;
    
    @ApiModelProperty("停车场ID")
    private Long parkingId;
    
    @ApiModelProperty("订单类型:1-代泊车 2-取车 3-接机 4-送机")
    private Integer orderType;
    
    @ApiModelProperty("订单状态")
    private Integer orderStatus;
    
    @ApiModelProperty("取车地址")
    private String pickupAddress;
    
    @ApiModelProperty("还车地址")
    private String returnAddress;
    
    @ApiModelProperty("取车时间")
    private LocalDateTime pickupTime;
    
    @ApiModelProperty("预计还车时间")
    private LocalDateTime estimatedReturnTime;
    
    @ApiModelProperty("实际还车时间")
    private LocalDateTime actualReturnTime;
    
    @ApiModelProperty("车辆品牌")
    private String carBrand;
    
    @ApiModelProperty("车牌号码")
    private String licensePlate;
    
    @ApiModelProperty("车辆颜色")
    private String carColor;
    
    @ApiModelProperty("订单金额")
    private BigDecimal orderAmount;
    
    @ApiModelProperty("服务时长(小时)")
    private BigDecimal serviceHours;
    
    @ApiModelProperty("停车费用")
    private BigDecimal parkingFee;
    
    @ApiModelProperty("服务费用")
    private BigDecimal serviceFee;
    
    @ApiModelProperty("订单备注")
    private String orderRemark;
    
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
}

// 服务人员实体类
@Data
@TableName("valet_staff")
@ApiModel(value = "ValetStaff对象", description = "服务人员表")
public class ValetStaff {
    @TableId(type = IdType.AUTO)
    @ApiModelProperty("服务人员ID")
    private Long valetId;
    
    @ApiModelProperty("用户ID")
    private Long userId;
    
    @ApiModelProperty("真实姓名")
    private String realName;
    
    @ApiModelProperty("手机号码")
    private String phone;
    
    @ApiModelProperty("身份证号")
    private String idCard;
    
    @ApiModelProperty("驾驶证号")
    private String driverLicense;
    
    @ApiModelProperty("服务类型:1-代泊车 2-机场接送")
    private String serviceTypes;
    
    @ApiModelProperty("当前状态:1-在线 2-忙碌 3-离线")
    private Integer currentStatus;
    
    @ApiModelProperty("当前位置经度")
    private BigDecimal currentLng;
    
    @ApiModelProperty("当前位置纬度")
    private BigDecimal currentLat;
    
    @ApiModelProperty("服务评分")
    private BigDecimal rating;
    
    @ApiModelProperty("接单数量")
    private Integer orderCount;
    
    @ApiModelProperty("审核状态")
    private Integer auditStatus;
    
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
}

// Mapper接口定义
public interface ValetOrderMapper extends BaseMapper<ValetOrder> {
    
    @Select("SELECT * FROM valet_order WHERE valet_id = #{valetId} AND order_status = #{status}")
    List<ValetOrder> selectByValetAndStatus(@Param("valetId") Long valetId, 
                                          @Param("status") Integer status);
    
    @Select("<script>" +
            "SELECT * FROM valet_order WHERE 1=1 " +
            "<if test='orderType != null'> AND order_type = #{orderType} </if>" +
            "<if test='orderStatus != null'> AND order_status = #{orderStatus} </if>" +
            "<if test='startTime != null'> AND create_time >= #{startTime} </if>" +
            "<if test='endTime != null'> AND create_time <= #{endTime} </if>" +
            " ORDER BY create_time DESC" +
            "</script>")
    List<ValetOrder> selectOrdersByConditions(@Param("orderType") Integer orderType,
                                            @Param("orderStatus") Integer orderStatus,
                                            @Param("startTime") LocalDateTime startTime,
                                            @Param("endTime") LocalDateTime endTime);
    
    @Update("UPDATE valet_order SET order_status = #{status} WHERE order_id = #{orderId}")
    int updateOrderStatus(@Param("orderId") Long orderId, @Param("status") Integer status);
    
    @Select("SELECT COUNT(*) FROM valet_order WHERE valet_id = #{valetId} " +
            "AND create_time >= #{startTime} AND create_time <= #{endTime}")
    Long countValetOrders(@Param("valetId") Long valetId,
                         @Param("startTime") LocalDateTime startTime,
                         @Param("endTime") LocalDateTime endTime);
}
业务逻辑层核心实现

JAVA代泊车接机送机服务代客泊车系统源码的业务逻辑层采用SpringBoot+MyBatisPlus技术栈,通过@Service注解实现业务逻辑,@Transactional确保数据一致性。

业务服务层代码示例:

复制代码
// 代泊车服务接口
public interface ValetService extends IService<ValetOrder> {
    
    OrderCreateResultVO createValetOrder(ValetOrderDTO orderDTO);
    
    boolean acceptOrder(Long orderId, Long valetId);
    
    boolean startService(Long orderId);
    
    boolean completeService(Long orderId);
    
    boolean cancelOrder(Long orderId, Long userId, String cancelReason);
    
    List<ValetStaffVO> findNearbyValets(LocationDTO locationDTO);
    
    OrderDetailVO getOrderDetail(Long orderId);
    
    boolean updateValetLocation(LocationUpdateDTO updateDTO);
}

// 代泊车服务实现类
@Service
@Slf4j
public class ValetServiceImpl extends ServiceImpl<ValetOrderMapper, ValetOrder> 
    implements ValetService {
    
    @Autowired
    private ValetStaffMapper valetStaffMapper;
    
    @Autowired
    private ParkingLotMapper parkingLotMapper;
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    @Autowired
    private GeoService geoService;
    
    @Autowired
    private DirectionService directionService;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderCreateResultVO createValetOrder(ValetOrderDTO orderDTO) {
        // 验证订单数据
        validateOrderDTO(orderDTO);
        
        // 创建订单
        ValetOrder order = new ValetOrder();
        BeanUtils.copyProperties(orderDTO, order);
        order.setOrderNo(generateOrderNo());
        order.setOrderStatus(1); // 待接单
        order.setOrderAmount(calculateOrderAmount(orderDTO));
        
        int result = baseMapper.insert(order);
        if (result > 0) {
            // 推送订单给附近服务人员
            pushOrderToNearbyValets(order);
            
            OrderCreateResultVO resultVO = new OrderCreateResultVO();
            resultVO.setOrderId(order.getOrderId());
            resultVO.setOrderNo(order.getOrderNo());
            resultVO.setOrderAmount(order.getOrderAmount());
            resultVO.setEstimatedWaitTime(calculateEstimatedWaitTime(order));
            
            log.info("创建代泊车订单成功,订单ID:{}", order.getOrderId());
            return resultVO;
        }
        
        throw new BusinessException("创建订单失败");
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean acceptOrder(Long orderId, Long valetId) {
        ValetOrder order = baseMapper.selectById(orderId);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }
        
        if (!order.getOrderStatus().equals(1)) {
            throw new BusinessException("订单状态不可接单");
        }
        
        // 检查服务人员是否可用
        ValetStaff valet = valetStaffMapper.selectById(valetId);
        if (valet == null || !valet.getCurrentStatus().equals(1)) {
            throw new BusinessException("服务人员当前不可用");
        }
        
        // 更新订单状态和服务人员信息
        order.setValetId(valetId);
        order.setOrderStatus(2); // 已接单
        order.setUpdateTime(LocalDateTime.now());
        
        int result = baseMapper.updateById(order);
        if (result > 0) {
            // 更新服务人员状态为忙碌
            valet.setCurrentStatus(2); // 忙碌
            valetStaffMapper.updateById(valet);
            
            // 发送接单通知
            sendOrderAcceptedNotification(order);
            return true;
        }
        
        return false;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean startService(Long orderId) {
        ValetOrder order = baseMapper.selectById(orderId);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }
        
        if (!order.getOrderStatus().equals(2)) {
            throw new BusinessException("订单状态不可开始服务");
        }
        
        // 更新订单状态
        order.setOrderStatus(3); // 服务中
        order.setUpdateTime(LocalDateTime.now());
        
        int result = baseMapper.updateById(order);
        if (result > 0) {
            // 记录服务开始时间
            order.setPickupTime(LocalDateTime.now());
            baseMapper.updateById(order);
            
            // 发送服务开始通知
            sendServiceStartNotification(order);
            return true;
        }
        
        return false;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean completeService(Long orderId) {
        ValetOrder order = baseMapper.selectById(orderId);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }
        
        if (!order.getOrderStatus().equals(3)) {
            throw new BusinessException("订单状态不可完成服务");
        }
        
        // 更新订单状态
        order.setOrderStatus(4); // 已完成
        order.setActualReturnTime(LocalDateTime.now());
        order.setUpdateTime(LocalDateTime.now());
        
        // 计算实际服务时长
        Duration duration = Duration.between(order.getPickupTime(), order.getActualReturnTime());
        BigDecimal actualHours = BigDecimal.valueOf(duration.toMinutes()).divide(BigDecimal.valueOf(60), 2, RoundingMode.HALF_UP);
        order.setServiceHours(actualHours);
        
        // 重新计算订单金额
        order.setOrderAmount(calculateActualOrderAmount(order));
        
        int result = baseMapper.updateById(order);
        if (result > 0) {
            // 更新服务人员状态为在线
            ValetStaff valet = valetStaffMapper.selectById(order.getValetId());
            valet.setCurrentStatus(1); // 在线
            valetStaffMapper.updateById(valet);
            
            // 更新服务人员评分和接单数量
            updateValetStatistics(order.getValetId());
            
            // 发送服务完成通知
            sendServiceCompleteNotification(order);
            return true;
        }
        
        return false;
    }
    
    @Override
    public List<ValetStaffVO> findNearbyValets(LocationDTO locationDTO) {
        // 从Redis获取附近在线的服务人员
        String cacheKey = "online_valets:" + locationDTO.getCityCode();
        List<ValetStaff> onlineValets = (List<ValetStaff>) redisTemplate.opsForValue().get(cacheKey);
        
        if (onlineValets == null) {
            // 从数据库查询在线服务人员
            LambdaQueryWrapper<ValetStaff> wrapper = Wrappers.lambdaQuery();
            wrapper.eq(ValetStaff::getCurrentStatus, 1) // 在线
                   .eq(ValetStaff::getAuditStatus, 2); // 已审核
            onlineValets = valetStaffMapper.selectList(wrapper);
            
            // 缓存到Redis,5分钟过期
            redisTemplate.opsForValue().set(cacheKey, onlineValets, 5, TimeUnit.MINUTES);
        }
        
        // 计算距离并筛选附近的服务人员
        return onlineValets.stream()
                .map(valet -> {
                    ValetStaffVO vo = new ValetStaffVO();
                    BeanUtils.copyProperties(valet, vo);
                    
                    // 计算距离
                    double distance = calculateDistance(
                        locationDTO.getLatitude(), locationDTO.getLongitude(),
                        valet.getCurrentLat().doubleValue(), valet.getCurrentLng().doubleValue()
                    );
                    vo.setDistance(distance);
                    vo.setEstimatedArrivalTime(calculateEstimatedArrivalTime(distance));
                    
                    return vo;
                })
                .filter(vo -> vo.getDistance() <= 10.0) // 10公里内的服务人员
                .sorted(Comparator.comparingDouble(ValetStaffVO::getDistance))
                .collect(Collectors.toList());
    }
    
    @Override
    public boolean updateValetLocation(LocationUpdateDTO updateDTO) {
        ValetStaff valet = valetStaffMapper.selectById(updateDTO.getValetId());
        if (valet == null) {
            throw new BusinessException("服务人员不存在");
        }
        
        // 更新服务人员位置
        valet.setCurrentLng(updateDTO.getLongitude());
        valet.setCurrentLat(updateDTO.getLatitude());
        valet.setUpdateTime(LocalDateTime.now());
        
        int result = valetStaffMapper.updateById(valet);
        if (result > 0) {
            // 更新Redis中的位置信息
            updateValetLocationInRedis(valet);
            return true;
        }
        
        return false;
    }
    
    private void validateOrderDTO(ValetOrderDTO orderDTO) {
        if (StringUtils.isBlank(orderDTO.getPickupAddress())) {
            throw new BusinessException("取车地址不能为空");
        }
        if (StringUtils.isBlank(orderDTO.getLicensePlate())) {
            throw new BusinessException("车牌号码不能为空");
        }
        if (orderDTO.getOrderType() == null) {
            throw new BusinessException("订单类型不能为空");
        }
    }
    
    private String generateOrderNo() {
        return "VT" + System.currentTimeMillis() + RandomUtil.randomNumbers(4);
    }
    
    private BigDecimal calculateOrderAmount(ValetOrderDTO orderDTO) {
        BigDecimal baseFee = new BigDecimal("20.00"); // 基础服务费
        
        // 根据服务类型、时长等计算费用
        if (orderDTO.getOrderType().equals(3) || orderDTO.getOrderType().equals(4)) {
            // 机场接送服务
            baseFee = new BigDecimal("50.00");
            
            // 计算距离费用
            try {
                Double distance = directionService.calculateDistance(
                    orderDTO.getPickupAddress(), orderDTO.getReturnAddress());
                BigDecimal distanceFee = new BigDecimal(distance * 0.5);
                baseFee = baseFee.add(distanceFee);
            } catch (Exception e) {
                log.warn("计算距离失败,使用基础费用", e);
            }
        }
        
        return baseFee;
    }
    
    private BigDecimal calculateActualOrderAmount(ValetOrder order) {
        BigDecimal baseAmount = order.getOrderAmount();
        
        // 根据实际服务时长调整费用
        if (order.getServiceHours().compareTo(new BigDecimal("1")) > 0) {
            // 超出基础时长的部分按小时计费
            BigDecimal extraHours = order.getServiceHours().subtract(new BigDecimal("1"));
            BigDecimal extraFee = extraHours.multiply(new BigDecimal("10.00"));
            baseAmount = baseAmount.add(extraFee);
        }
        
        // 加上停车费用
        if (order.getParkingFee() != null) {
            baseAmount = baseAmount.add(order.getParkingFee());
        }
        
        return baseAmount;
    }
    
    private void pushOrderToNearbyValets(ValetOrder order) {
        LocationDTO locationDTO = new LocationDTO();
        locationDTO.setLatitude(order.getPickupLat().doubleValue());
        locationDTO.setLongitude(order.getPickupLng().doubleValue());
        locationDTO.setCityCode(order.getCityCode());
        
        List<ValetStaffVO> nearbyValets = findNearbyValets(locationDTO);
        
        // 推送订单给附近服务人员
        nearbyValets.forEach(valet -> {
            String message = String.format("新订单提醒:%s,服务费:%s元", 
                getOrderTypeText(order.getOrderType()), order.getOrderAmount());
            pushMessageToValet(valet.getValetId(), message);
        });
    }
    
    private String getOrderTypeText(Integer orderType) {
        switch (orderType) {
            case 1: return "代泊车服务";
            case 2: return "取车服务";
            case 3: return "接机服务";
            case 4: return "送机服务";
            default: return "其他服务";
        }
    }
    
    private double calculateDistance(double lat1, double lng1, double lat2, double lng2) {
        // 实现距离计算逻辑(Haversine公式)
        double earthRadius = 6371; // 地球半径,单位公里
        double dLat = Math.toRadians(lat2 - lat1);
        double dLng = Math.toRadians(lng2 - lng1);
        double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
                   Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
                   Math.sin(dLng / 2) * Math.sin(dLng / 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        return earthRadius * c;
    }
    
    private String calculateEstimatedArrivalTime(double distance) {
        // 根据距离估算到达时间(考虑交通状况)
        double speed = 30.0; // 平均速度30km/h
        double timeInMinutes = (distance / speed) * 60;
        
        if (timeInMinutes < 10) {
            return "10分钟内";
        } else if (timeInMinutes < 20) {
            return "20分钟内";
        } else if (timeInMinutes < 30) {
            return "30分钟内";
        } else {
            return "1小时内";
        }
    }
    
    private String calculateEstimatedWaitTime(ValetOrder order) {
        // 根据附近服务人员数量和距离估算等待时间
        LocationDTO locationDTO = new LocationDTO();
        locationDTO.setLatitude(order.getPickupLat().doubleValue());
        locationDTO.setLongitude(order.getPickupLng().doubleValue());
        
        List<ValetStaffVO> nearbyValets = findNearbyValets(locationDTO);
        
        if (nearbyValets.isEmpty()) {
            return "30分钟以上";
        }
        
        // 取最近的服务人员的预计到达时间
        return nearbyValets.get(0).getEstimatedArrivalTime();
    }
    
    private void updateValetStatistics(Long valetId) {
        // 更新服务人员的评分和接单数量统计
        ValetStaff valet = valetStaffMapper.selectById(valetId);
        valet.setOrderCount(valet.getOrderCount() + 1);
        
        // 这里可以添加更复杂的评分计算逻辑
        // 例如根据用户评价更新评分
        
        valetStaffMapper.updateById(valet);
    }
    
    private void updateValetLocationInRedis(ValetStaff valet) {
        // 更新Redis中服务人员的位置信息
        String locationKey = "valet_location:" + valet.getValetId();
        Map<String, Object> locationData = new HashMap<>();
        locationData.put("lng", valet.getCurrentLng());
        locationData.put("lat", valet.getCurrentLat());
        locationData.put("updateTime", LocalDateTime.now());
        
        redisTemplate.opsForHash().putAll(locationKey, locationData);
        redisTemplate.expire(locationKey, 10, TimeUnit.MINUTES);
    }
}
机场接送服务核心实现

机场接送服务代码示例:

复制代码
// 机场接送服务接口
public interface AirportService extends IService<ValetOrder> {
    
    OrderCreateResultVO createAirportOrder(AirportOrderDTO orderDTO);
    
    List<AirportScheduleVO> getAirportSchedules(String airportCode);
    
    boolean updateFlightInfo(FlightUpdateDTO updateDTO);
    
    BigDecimal calculateAirportFee(AirportFeeDTO feeDTO);
}

// 机场接送服务实现类
@Service
@Slf4j
public class AirportServiceImpl extends ServiceImpl<ValetOrderMapper, ValetOrder> 
    implements AirportService {
    
    @Autowired
    private AirportInfoMapper airportInfoMapper;
    
    @Autowired
    private FlightService flightService;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderCreateResultVO createAirportOrder(AirportOrderDTO orderDTO) {
        // 验证机场订单数据
        validateAirportOrderDTO(orderDTO);
        
        // 创建机场接送订单
        ValetOrder order = new ValetOrder();
        BeanUtils.copyProperties(orderDTO, order);
        order.setOrderNo(generateAirportOrderNo());
        order.setOrderStatus(1); // 待接单
        order.setOrderType(orderDTO.getServiceType()); // 3-接机 4-送机
        order.setOrderAmount(calculateAirportOrderAmount(orderDTO));
        
        int result = baseMapper.insert(order);
        if (result > 0) {
            // 如果是接机服务,查询航班信息
            if (orderDTO.getServiceType().equals(3) && StringUtils.isNotBlank(orderDTO.getFlightNumber())) {
                updateFlightInfoForOrder(order.getOrderId(), orderDTO.getFlightNumber());
            }
            
            OrderCreateResultVO resultVO = new OrderCreateResultVO();
            resultVO.setOrderId(order.getOrderId());
            resultVO.setOrderNo(order.getOrderNo());
            resultVO.setOrderAmount(order.getOrderAmount());
            resultVO.setEstimatedWaitTime("正在分配服务人员");
            
            log.info("创建机场接送订单成功,订单ID:{}", order.getOrderId());
            return resultVO;
        }
        
        throw new BusinessException("创建订单失败");
    }
    
    @Override
    public List<AirportScheduleVO> getAirportSchedules(String airportCode) {
        // 从Redis获取机场班次信息
        String cacheKey = "airport_schedules:" + airportCode;
        List<AirportScheduleVO> cachedSchedules = (List<AirportScheduleVO>) redisTemplate.opsForValue().get(cacheKey);
        
        if (cachedSchedules != null) {
            return cachedSchedules;
        }
        
        // 查询数据库中的机场信息
        AirportInfo airportInfo = airportInfoMapper.selectByCode(airportCode);
        if (airportInfo == null) {
            throw new BusinessException("机场信息不存在");
        }
        
        // 生成接送班次信息
        List<AirportScheduleVO> schedules = generateAirportSchedules(airportInfo);
        
        // 缓存结果,1小时过期
        redisTemplate.opsForValue().set(cacheKey, schedules, 1, TimeUnit.HOURS);
        
        return schedules;
    }
    
    @Override
    public boolean updateFlightInfo(FlightUpdateDTO updateDTO) {
        ValetOrder order = baseMapper.selectById(updateDTO.getOrderId());
        if (order == null) {
            throw new BusinessException("订单不存在");
        }
        
        // 更新航班信息
        order.setFlightNumber(updateDTO.getFlightNumber());
        order.setFlightStatus(updateDTO.getFlightStatus());
        order.setEstimatedArrivalTime(updateDTO.getEstimatedTime());
        order.setUpdateTime(LocalDateTime.now());
        
        int result = baseMapper.updateById(order);
        if (result > 0) {
            // 通知服务人员航班信息变更
            notifyValetFlightUpdate(order);
            return true;
        }
        
        return false;
    }
    
    @Override
    public BigDecimal calculateAirportFee(AirportFeeDTO feeDTO) {
        BigDecimal baseFee = new BigDecimal("50.00"); // 基础接送费
        
        // 计算距离费用
        try {
            Double distance = directionService.calculateDistance(
                feeDTO.getPickupAddress(), feeDTO.getDestinationAddress());
            BigDecimal distanceFee = new BigDecimal(distance * 0.8); // 每公里0.8元
            baseFee = baseFee.add(distanceFee);
        } catch (Exception e) {
            log.warn("计算距离失败,使用基础费用", e);
        }
        
        // 时间附加费(夜间、高峰时段)
        if (isPeakTime(feeDTO.getServiceTime())) {
            baseFee = baseFee.add(new BigDecimal("20.00")); // 高峰时段附加费
        }
        
        if (isNightTime(feeDTO.getServiceTime())) {
            baseFee = baseFee.add(new BigDecimal("30.00")); // 夜间服务附加费
        }
        
        // 车型附加费
        if (StringUtils.isNotBlank(feeDTO.getCarType()) && 
            feeDTO.getCarType().equals("premium")) {
            baseFee = baseFee.add(new BigDecimal("50.00")); // 豪华车型附加费
        }
        
        return baseFee.setScale(2, RoundingMode.HALF_UP);
    }
    
    private void validateAirportOrderDTO(AirportOrderDTO orderDTO) {
        if (StringUtils.isBlank(orderDTO.getPickupAddress())) {
            throw new BusinessException("接送地址不能为空");
        }
        if (StringUtils.isBlank(orderDTO.getDestinationAddress())) {
            throw new BusinessException("目的地地址不能为空");
        }
        if (orderDTO.getServiceType() == null) {
            throw new BusinessException("服务类型不能为空");
        }
        if (orderDTO.getServiceTime() == null) {
            throw new BusinessException("服务时间不能为空");
        }
    }
    
    private String generateAirportOrderNo() {
        return "AP" + System.currentTimeMillis() + RandomUtil.randomNumbers(4);
    }
    
    private BigDecimal calculateAirportOrderAmount(AirportOrderDTO orderDTO) {
        AirportFeeDTO feeDTO = new AirportFeeDTO();
        feeDTO.setPickupAddress(orderDTO.getPickupAddress());
        feeDTO.setDestinationAddress(orderDTO.getDestinationAddress());
        feeDTO.setServiceTime(orderDTO.getServiceTime());
        feeDTO.setCarType(orderDTO.getCarType());
        
        return calculateAirportFee(feeDTO);
    }
    
    private void updateFlightInfoForOrder(Long orderId, String flightNumber) {
        try {
            // 调用航班信息API获取实时航班状态
            FlightInfo flightInfo = flightService.getFlightInfo(flightNumber);
            
            FlightUpdateDTO updateDTO = new FlightUpdateDTO();
            updateDTO.setOrderId(orderId);
            updateDTO.setFlightNumber(flightNumber);
            updateDTO.setFlightStatus(flightInfo.getStatus());
            updateDTO.setEstimatedTime(flightInfo.getEstimatedArrivalTime());
            
            updateFlightInfo(updateDTO);
        } catch (Exception e) {
            log.warn("获取航班信息失败: {}", flightNumber, e);
        }
    }
    
    private List<AirportScheduleVO> generateAirportSchedules(AirportInfo airportInfo) {
        List<AirportScheduleVO> schedules = new ArrayList<>();
        LocalDateTime now = LocalDateTime.now();
        
        // 生成未来24小时的接送班次
        for (int i = 0; i < 24; i++) {
            AirportScheduleVO schedule = new AirportScheduleVO();
            schedule.setDepartureTime(now.plusHours(i));
            schedule.setAvailableSeats(4); // 每班次4个座位
            schedule.setPrice(new BigDecimal("25.00")); // 班次价格
            schedule.setRoute(airportInfo.getAirportName() + " - 市区");
            schedules.add(schedule);
        }
        
        return schedules;
    }
    
    private boolean isPeakTime(LocalDateTime serviceTime) {
        LocalTime time = serviceTime.toLocalTime();
        return (time.isAfter(LocalTime.of(7, 0)) && time.isBefore(LocalTime.of(9, 0))) ||
               (time.isAfter(LocalTime.of(17, 0)) && time.isBefore(LocalTime.of(19, 0)));
    }
    
    private boolean isNightTime(LocalDateTime serviceTime) {
        LocalTime time = serviceTime.toLocalTime();
        return time.isAfter(LocalTime.of(22, 0)) || time.isBefore(LocalTime.of(6, 0));
    }
    
    private void notifyValetFlightUpdate(ValetOrder order) {
        // 通知服务人员航班信息变更
        if (order.getValetId() != null) {
            String message = String.format("航班信息更新:%s %s", 
                order.getFlightNumber(), order.getFlightStatus());
            pushMessageToValet(order.getValetId(), message);
        }
    }
}
控制层和API接口设计

RESTful API设计遵循行业标准,提供统一的响应格式和完整的错误处理机制。

控制器代码示例:

复制代码
// 代泊车服务控制器
@RestController
@RequestMapping("/api/valet")
@Api(tags = "代泊车服务管理")
@Slf4j
public class ValetController {
    
    @Autowired
    private ValetService valetService;
    
    @PostMapping("/order/create")
    @ApiOperation("创建代泊车订单")
    public Result<OrderCreateResultVO> createValetOrder(@RequestBody @Valid ValetOrderDTO orderDTO) {
        try {
            OrderCreateResultVO result = valetService.createValetOrder(orderDTO);
            return Result.success("创建订单成功", result);
        } catch (BusinessException e) {
            return Result.error(e.getMessage());
        } catch (Exception e) {
            log.error("创建代泊车订单失败", e);
            return Result.error("创建订单失败");
        }
    }
    
    @PostMapping("/order/accept/{orderId}")
    @ApiOperation("接单")
    public Result<String> acceptOrder(@PathVariable Long orderId, @RequestParam Long valetId) {
        try {
            boolean success = valetService.acceptOrder(orderId, valetId);
            return success ? Result.success("接单成功") : Result.error("接单失败");
        } catch (BusinessException e) {
            return Result.error(e.getMessage());
        } catch (Exception e) {
            log.error("接单失败", e);
            return Result.error("接单失败");
        }
    }
    
    @PostMapping("/order/start/{orderId}")
    @ApiOperation("开始服务")
    public Result<String> startService(@PathVariable Long orderId) {
        try {
            boolean success = valetService.startService(orderId);
            return success ? Result.success("开始服务成功") : Result.error("开始服务失败");
        } catch (BusinessException e) {
            return Result.error(e.getMessage());
        } catch (Exception e) {
            log.error("开始服务失败", e);
            return Result.error("开始服务失败");
        }
    }
    
    @PostMapping("/order/complete/{orderId}")
    @ApiOperation("完成服务")
    public Result<String> completeService(@PathVariable Long orderId) {
        try {
            boolean success = valetService.completeService(orderId);
            return success ? Result.success("完成服务成功") : Result.error("完成服务失败");
        } catch (BusinessException e) {
            return Result.error(e.getMessage());
        } catch (Exception e) {
            log.error("完成服务失败", e);
            return Result.error("完成服务失败");
        }
    }
    
    @GetMapping("/nearby-valets")
    @ApiOperation("查找附近服务人员")
    public Result<List<ValetStaffVO>> findNearbyValets(LocationDTO locationDTO) {
        try {
            List<ValetStaffVO> valets = valetService.findNearbyValets(locationDTO);
            return Result.success("查找附近服务人员成功", valets);
        } catch (Exception e) {
            log.error("查找附近服务人员失败", e);
            return Result.error("查找附近服务人员失败");
        }
    }
    
    @PostMapping("/location/update")
    @ApiOperation("更新服务人员位置")
    public Result<String> updateValetLocation(@RequestBody @Valid LocationUpdateDTO updateDTO) {
        try {
            boolean success = valetService.updateValetLocation(updateDTO);
            return success ? Result.success("更新位置成功") : Result.error("更新位置失败");
        } catch (BusinessException e) {
            return Result.error(e.getMessage());
        } catch (Exception e) {
            log.error("更新服务人员位置失败", e);
            return Result.error("更新位置失败");
        }
    }
}

// 机场接送控制器
@RestController
@RequestMapping("/api/airport")
@Api(tags = "机场接送服务")
@Slf4j
public class AirportController {
    
    @Autowired
    private AirportService airportService;
    
    @PostMapping("/order/create")
    @ApiOperation("创建机场接送订单")
    public Result<OrderCreateResultVO> createAirportOrder(@RequestBody @Valid AirportOrderDTO orderDTO) {
        try {
            OrderCreateResultVO result = airportService.createAirportOrder(orderDTO);
            return Result.success("创建机场接送订单成功", result);
        } catch (BusinessException e) {
            return Result.error(e.getMessage());
        } catch (Exception e) {
            log.error("创建机场接送订单失败", e);
            return Result.error("创建订单失败");
        }
    }
    
    @GetMapping("/schedules/{airportCode}")
    @ApiOperation("获取机场班次信息")
    public Result<List<AirportScheduleVO>> getAirportSchedules(@PathVariable String airportCode) {
        try {
            List<AirportScheduleVO> schedules = airportService.getAirportSchedules(airportCode);
            return Result.success("获取机场班次信息成功", schedules);
        } catch (BusinessException e) {
            return Result.error(e.getMessage());
        } catch (Exception e) {
            log.error("获取机场班次信息失败", e);
            return Result.error("获取班次信息失败");
        }
    }
    
    @PostMapping("/flight/update")
    @ApiOperation("更新航班信息")
    public Result<String> updateFlightInfo(@RequestBody @Valid FlightUpdateDTO updateDTO) {
        try {
            boolean success = airportService.updateFlightInfo(updateDTO);
            return success ? Result.success("更新航班信息成功") : Result.error("更新航班信息失败");
        } catch (BusinessException e) {
            return Result.error(e.getMessage());
        } catch (Exception e) {
            log.error("更新航班信息失败", e);
            return Result.error("更新航班信息失败");
        }
    }
    
    @PostMapping("/fee/calculate")
    @ApiOperation("计算机场接送费用")
    public Result<BigDecimal> calculateAirportFee(@RequestBody @Valid AirportFeeDTO feeDTO) {
        try {
            BigDecimal fee = airportService.calculateAirportFee(feeDTO);
            return Result.success("计算费用成功", fee);
        } catch (Exception e) {
            log.error("计算机场接送费用失败", e);
            return Result.error("计算费用失败");
        }
    }
}

// 统一响应结果封装
@Data
@ApiModel("统一响应结果")
public class Result<T> implements Serializable {
    
    @ApiModelProperty("状态码")
    private Integer code;
    
    @ApiModelProperty("响应消息")
    private String message;
    
    @ApiModelProperty("响应数据")
    private T data;
    
    @ApiModelProperty("时间戳")
    private Long timestamp;
    
    public static <T> Result<T> success(String message, T data) {
        Result<T> result = new Result<>();
        result.setCode(200);
        result.setMessage(message);
        result.setData(data);
        result.setTimestamp(System.currentTimeMillis());
        return result;
    }
    
    public static <T> Result<T> success(String message) {
        return success(message, null);
    }
    
    public static <T> Result<T> error(String message) {
        Result<T> result = new Result<>();
        result.setCode(500);
        result.setMessage(message);
        result.setTimestamp(System.currentTimeMillis());
        return result;
    }
}
前端uniapp用户端实现

用户端采用uniapp开发,支持编译到小程序、APP、H5等多个平台,为JAVA代泊车接机送机服务代客泊车系统源码提供一致的用户体验。

Vue组件代码示例:

复制代码
<template>
  <view class="valet-service-container">
    <!-- 顶部导航 -->
    <view class="header-section">
      <view class="location-info">
        <u-icon name="map" size="36" color="#007aff"></u-icon>
        <text class="current-location">{{ currentLocation }}</text>
        <u-icon name="arrow-down" size="28" color="#666"></u-icon>
      </view>
    </view>

    <!-- 服务类型选择 -->
    <view class="service-type-section">
      <view class="section-title">选择服务类型</view>
      <view class="service-type-grid">
        <view 
          v-for="service in serviceTypes" 
          :key="service.type"
          class="service-type-item"
          :class="{ active: selectedService === service.type }"
          @click="selectServiceType(service.type)"
        >
          <image :src="service.icon" class="service-icon"></image>
          <text class="service-name">{{ service.name }}</text>
          <text class="service-desc">{{ service.description }}</text>
        </view>
      </view>
    </view>

    <!-- 代泊车服务表单 -->
    <view v-if="selectedService === 1" class="service-form">
      <view class="form-section">
        <view class="form-title">车辆信息</view>
        <view class="form-group">
          <view class="form-label">车牌号码</view>
          <u-input
            v-model="carInfo.licensePlate"
            placeholder="请输入车牌号码"
            border="none"
          />
        </view>
        <view class="form-group">
          <view class="form-label">车辆品牌</view>
          <u-input
            v-model="carInfo.carBrand"
            placeholder="请输入车辆品牌"
            border="none"
          />
        </view>
        <view class="form-group">
          <view class="form-label">车辆颜色</view>
          <u-input
            v-model="carInfo.carColor"
            placeholder="请输入车辆颜色"
            border="none"
          />
        </view>
      </view>

      <view class="form-section">
        <view class="form-title">服务信息</view>
        <view class="form-group">
          <view class="form-label">取车地点</view>
          <view class="location-input" @click="choosePickupLocation">
            <text class="location-text" v-if="pickupAddress">{{ pickupAddress }}</text>
            <text class="location-placeholder" v-else>请选择取车地点</text>
            <u-icon name="map-fill" size="32" color="#999"></u-icon>
          </view>
        </view>
        <view class="form-group">
          <view class="form-label">预计还车时间</view>
          <u-datetime-picker
            v-model="estimatedReturnTime"
            :min-date="minDate"
            :max-date="maxDate"
            mode="datetime"
          >
            <view class="time-input" @click="showTimePicker = true">
              <text class="time-text" v-if="estimatedReturnTime">
                {{ formatTime(estimatedReturnTime) }}
              </text>
              <text class="time-placeholder" v-else>请选择还车时间</text>
              <u-icon name="calendar" size="32" color="#999"></u-icon>
            </view>
          </u-datetime-picker>
        </view>
      </view>
    </view>

    <!-- 机场接送服务表单 -->
    <view v-if="selectedService === 3 || selectedService === 4" class="service-form">
      <view class="form-section">
        <view class="form-title">接送信息</view>
        <view class="form-group">
          <view class="form-label">{{ selectedService === 3 ? '接机地址' : '送机地址' }}</view>
          <view class="location-input" @click="choosePickupLocation">
            <text class="location-text" v-if="pickupAddress">{{ pickupAddress }}</text>
            <text class="location-placeholder" v-else>请选择地址</text>
            <u-icon name="map-fill" size="32" color="#999"></u-icon>
          </view>
        </view>
        <view class="form-group">
          <view class="form-label">{{ selectedService === 3 ? '目的地' : '机场' }}</view>
          <view class="location-input" @click="chooseDestinationLocation">
            <text class="location-text" v-if="destinationAddress">{{ destinationAddress }}</text>
            <text class="location-placeholder" v-else>
              {{ selectedService === 3 ? '请选择目的地' : '请选择机场' }}
            </text>
            <u-icon name="map-fill" size="32" color="#999"></u-icon>
          </view>
        </view>
        <view class="form-group" v-if="selectedService === 3">
          <view class="form-label">航班号</view>
          <u-input
            v-model="flightInfo.flightNumber"
            placeholder="请输入航班号"
            border="none"
          />
        </view>
        <view class="form-group">
          <view class="form-label">服务时间</view>
          <u-datetime-picker
            v-model="serviceTime"
            :min-date="minDate"
            :max-date="maxDate"
            mode="datetime"
          >
            <view class="time-input" @click="showTimePicker = true">
              <text class="time-text" v-if="serviceTime">
                {{ formatTime(serviceTime) }}
              </text>
              <text class="time-placeholder" v-else>请选择服务时间</text>
              <u-icon name="calendar" size="32" color="#999"></u-icon>
            </view>
          </u-datetime-picker>
        </view>
      </view>
    </view>

    <!-- 费用估算 -->
    <view class="fee-estimate">
      <view class="fee-item">
        <text class="fee-label">预估费用</text>
        <text class="fee-amount">¥{{ estimatedFee }}</text>
      </view>
      <text class="fee-desc">最终费用以实际服务为准</text>
    </view>

    <!-- 立即预约按钮 -->
    <view class="booking-section">
      <u-button
        type="primary"
        shape="circle"
        :disabled="!canBook"
        @click="handleBooking"
      >
        立即预约
      </u-button>
    </view>

    <!-- 地址选择地图 -->
    <u-popup
      v-model="showMapPicker"
      mode="bottom"
      border-radius="20"
    >
      <map-picker
        v-if="showMapPicker"
        :type="mapPickerType"
        @confirm="onAddressConfirm"
        @cancel="showMapPicker = false"
      />
    </u-popup>
  </view>
</template>

<script>
export default {
  data() {
    return {
      selectedService: 1,
      serviceTypes: [
        { 
          type: 1, 
          name: '代泊车', 
          description: '专业代客停车', 
          icon: '/static/icons/valet.png' 
        },
        { 
          type: 2, 
          name: '取车', 
          description: '预约取回车辆', 
          icon: '/static/icons/car-return.png' 
        },
        { 
          type: 3, 
          name: '接机', 
          description: '机场专车接机', 
          icon: '/static/icons/pickup.png' 
        },
        { 
          type: 4, 
          name: '送机', 
          description: '机场专车送机', 
          icon: '/static/icons/dropoff.png' 
        }
      ],
      currentLocation: '定位中...',
      carInfo: {
        licensePlate: '',
        carBrand: '',
        carColor: ''
      },
      pickupAddress: '',
      pickupLat: null,
      pickupLng: null,
      destinationAddress: '',
      destinationLat: null,
      destinationLng: null,
      estimatedReturnTime: null,
      serviceTime: null,
      flightInfo: {
        flightNumber: ''
      },
      estimatedFee: '0.00',
      showMapPicker: false,
      mapPickerType: 'pickup',
      minDate: Date.now(),
      maxDate: Date.now() + 30 * 24 * 60 * 60 * 1000 // 30天后
    }
  },

  computed: {
    canBook() {
      switch (this.selectedService) {
        case 1: // 代泊车
          return this.carInfo.licensePlate && 
                 this.pickupAddress && 
                 this.estimatedReturnTime
        case 3: // 接机
        case 4: // 送机
          return this.pickupAddress && 
                 this.destinationAddress && 
                 this.serviceTime
        default:
          return false
      }
    }
  },

  onLoad() {
    this.getCurrentLocation()
    this.calculateEstimatedFee()
  },

  watch: {
    selectedService() {
      this.calculateEstimatedFee()
    },
    pickupAddress() {
      this.calculateEstimatedFee()
    },
    destinationAddress() {
      this.calculateEstimatedFee()
    }
  },

  methods: {
    selectServiceType(serviceType) {
      this.selectedService = serviceType
      this.resetForm()
    },

    choosePickupLocation() {
      this.mapPickerType = 'pickup'
      this.showMapPicker = true
    },

    chooseDestinationLocation() {
      this.mapPickerType = 'destination'
      this.showMapPicker = true
    },

    onAddressConfirm(addressData) {
      if (this.mapPickerType === 'pickup') {
        this.pickupAddress = addressData.address
        this.pickupLat = addressData.latitude
        this.pickupLng = addressData.longitude
      } else {
        this.destinationAddress = addressData.address
        this.destinationLat = addressData.latitude
        this.destinationLng = addressData.longitude
      }
      this.showMapPicker = false
      this.calculateEstimatedFee()
    },

    async calculateEstimatedFee() {
      if (!this.pickupAddress) return

      try {
        let feeData = {
          pickupAddress: this.pickupAddress,
          serviceType: this.selectedService
        }

        if (this.selectedService === 3 || this.selectedService === 4) {
          if (!this.destinationAddress) return
          feeData.destinationAddress = this.destinationAddress
          feeData.serviceTime = this.serviceTime
        }

        const res = await this.$http.post('/api/service/calculate-fee', feeData)
        if (res.code === 200) {
          this.estimatedFee = res.data
        }
      } catch (error) {
        console.error('计算预估费用失败:', error)
      }
    },

    async handleBooking() {
      if (!this.canBook) {
        uni.showToast({
          title: '请完善订单信息',
          icon: 'none'
        })
        return
      }

      try {
        let orderData = {
          serviceType: this.selectedService,
          pickupAddress: this.pickupAddress,
          pickupLat: this.pickupLat,
          pickupLng: this.pickupLng
        }

        if (this.selectedService === 1) {
          // 代泊车订单
          Object.assign(orderData, {
            licensePlate: this.carInfo.licensePlate,
            carBrand: this.carInfo.carBrand,
            carColor: this.carInfo.carColor,
            estimatedReturnTime: this.estimatedReturnTime
          })
        } else if (this.selectedService === 3 || this.selectedService === 4) {
          // 机场接送订单
          Object.assign(orderData, {
            destinationAddress: this.destinationAddress,
            destinationLat: this.destinationLat,
            destinationLng: this.destinationLng,
            serviceTime: this.serviceTime,
            flightNumber: this.flightInfo.flightNumber
          })
        }

        const res = await this.$http.post('/api/valet/order/create', orderData)
        
        if (res.code === 200) {
          uni.showToast({
            title: '预约成功',
            icon: 'success'
          })
          
          // 跳转到订单详情页
          setTimeout(() => {
            uni.navigateTo({
              url: `/pages/order/detail?id=${res.data.orderId}`
            })
          }, 1500)
        } else {
          uni.showToast({
            title: res.message || '预约失败',
            icon: 'none'
          })
        }
      } catch (error) {
        console.error('预约失败:', error)
        uni.showToast({
          title: '网络错误,请重试',
          icon: 'none'
        })
      }
    },

    resetForm() {
      this.carInfo = {
        licensePlate: '',
        carBrand: '',
        carColor: ''
      }
      this.pickupAddress = ''
      this.destinationAddress = ''
      this.estimatedReturnTime = null
      this.serviceTime = null
      this.flightInfo.flightNumber = ''
    },

    formatTime(timestamp) {
      if (!timestamp) return ''
      const date = new Date(timestamp)
      return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()} ${date.getHours()}:${date.getMinutes()}`
    },

    getCurrentLocation() {
      uni.getLocation({
        type: 'gcj02',
        success: (res) => {
          // 逆地理编码获取具体地址
          this.reverseGeocode(res.latitude, res.longitude)
        },
        fail: (error) => {
          console.error('获取位置失败:', error)
          this.currentLocation = '获取位置失败'
        }
      })
    },

    async reverseGeocode(latitude, longitude) {
      try {
        const res = await this.$http.get('/api/location/reverse-geocode', {
          params: { latitude, longitude }
        })
        if (res.code === 200) {
          this.currentLocation = res.data.address
        }
      } catch (error) {
        console.error('逆地理编码失败:', error)
        this.currentLocation = '位置信息'
      }
    }
  }
}
</script>

<style scoped>
.valet-service-container {
  padding: 30rpx;
  background-color: #f5f5f5;
  min-height: 100vh;
  padding-bottom: 120rpx;
}

.header-section {
  margin-bottom: 30rpx;
}

.location-info {
  display: flex;
  align-items: center;
}

.current-location {
  font-size: 32rpx;
  font-weight: bold;
  color: #333;
  margin: 0 10rpx;
}

.service-type-section {
  background: #fff;
  border-radius: 20rpx;
  padding: 30rpx;
  margin-bottom: 30rpx;
}

.section-title {
  font-size: 32rpx;
  font-weight: bold;
  color: #333;
  margin-bottom: 30rpx;
}

.service-type-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 30rpx;
}

.service-type-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 30rpx;
  background: #f8f8f8;
  border-radius: 16rpx;
  border: 2rpx solid transparent;
  transition: all 0.3s;
}

.service-type-item.active {
  border-color: #007aff;
  background: #f0f8ff;
  transform: translateY(-5rpx);
}

.service-icon {
  width: 80rpx;
  height: 80rpx;
  margin-bottom: 20rpx;
}

.service-name {
  font-size: 28rpx;
  font-weight: bold;
  color: #333;
  margin-bottom: 10rpx;
}

.service-desc {
  font-size: 24rpx;
  color: #666;
}

.service-form {
  background: #fff;
  border-radius: 20rpx;
  padding: 30rpx;
  margin-bottom: 30rpx;
}

.form-section {
  margin-bottom: 40rpx;
}

.form-title {
  font-size: 28rpx;
  font-weight: bold;
  color: #333;
  margin-bottom: 30rpx;
  padding-bottom: 20rpx;
  border-bottom: 1rpx solid #f0f0f0;
}

.form-group {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 25rpx 0;
  border-bottom: 1rpx solid #f8f8f8;
}

.form-label {
  font-size: 28rpx;
  color: #333;
  width: 200rpx;
}

.location-input,
.time-input {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex: 1;
  padding: 20rpx;
  background: #f8f8f8;
  border-radius: 12rpx;
}

.location-text,
.time-text {
  font-size: 28rpx;
  color: #333;
  flex: 1;
}

.location-placeholder,
.time-placeholder {
  font-size: 28rpx;
  color: #999;
  flex: 1;
}

.fee-estimate {
  background: #fff;
  border-radius: 20rpx;
  padding: 30rpx;
  margin-bottom: 30rpx;
  text-align: center;
}

.fee-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20rpx;
}

.fee-label {
  font-size: 28rpx;
  color: #333;
}

.fee-amount {
  font-size: 36rpx;
  color: #ff6b35;
  font-weight: bold;
}

.fee-desc {
  font-size: 24rpx;
  color: #999;
}

.booking-section {
  padding: 0 30rpx;
}
</style>
系统特色与行业价值

JAVA代泊车接机送机服务代客泊车系统源码通过技术创新和业务整合,为出行服务行业提供了全方位的数字化解决方案。这套JAVA代泊车接机送机服务代客泊车系统源码具备以下核心优势:

技术架构优势:

  • 前后端分离架构,提高开发效率和系统稳定性
  • 多端统一开发,大幅降低维护成本
  • 实时位置追踪,确保服务过程透明
  • 智能调度算法,优化服务资源配置

业务功能优势:

  • 全场景服务覆盖,满足多样化出行需求
  • 实时航班信息集成,提升机场接送体验
  • 智能费用计算,确保价格透明合理
  • 完善评价体系,建立服务质量标准

性能与安全:

  • Redis缓存优化,提升系统响应速度
  • 数据库读写分离,支持高并发访问
  • 支付安全加密,保障交易安全
  • 实时监控系统,确保服务可靠性

JAVA代泊车接机送机服务代客泊车系统源码以其全面的技术栈和创新的业务模式,为出行服务行业提供了真正意义上的一站式数字化解决方案。从后台的springboot+mybatisplus+mysql稳定架构,到用户端的uniapp跨平台实现,再到管理后台的vue+elementUi优雅界面,每一个技术选型都经过精心考量,确保系统在性能、可维护性和用户体验方面达到最佳平衡。

随着城市化进程的加速和出行需求的持续增长,拥有这样一套完整的JAVA代泊车接机送机服务代客泊车系统源码将成为出行服务企业的核心竞争优势。无论是传统代泊车公司寻求数字化转型,还是新兴出行平台希望拓展服务边界,这套JAVA代泊车接机送机服务代客泊车系统源码都能提供强有力的技术支撑和业务保障,助力企业在激烈的市场竞争中脱颖而出,推动整个出行服务行业向数字化、智能化、标准化方向发展。

相关推荐
earthzhang20216 小时前
【1028】字符菱形
c语言·开发语言·数据结构·c++·算法·青少年编程
earthzhang20218 小时前
第3讲:Go垃圾回收机制与性能优化
开发语言·jvm·数据结构·后端·性能优化·golang
apocelipes9 小时前
golang unique包和字符串内部化
java·python·性能优化·golang
纵有疾風起9 小时前
C++——类和对象(3)
开发语言·c++·经验分享·开源
木易 士心10 小时前
组织架构树形选择组件使用说明(Vue3 + UniApp)
微信小程序·钉钉·notepad++
Full Stack Developme10 小时前
java.text 包详解
java·开发语言·python
文火冰糖的硅基工坊10 小时前
[嵌入式系统-135]:主流AIOT智能体开发板
开发语言·嵌入式·cpu
刘梦凡呀11 小时前
C#获取钉钉平台考勤记录
java·c#·钉钉
软件技术员11 小时前
微信小程序电子测宅堪墓风水罗盘
微信小程序·小程序