Files
oneapp_docs/app_car/app_charging.md
2025-09-24 14:08:54 +08:00

27 KiB
Raw Blame History

App Charging - 充电管理模块文档

模块概述

app_charging 是 OneApp 的充电管理核心模块提供完整的电动车充电功能包括充电地图、充电站查找、订单管理、支付结算等全流程充电服务。该模块集成了高德地图服务、BLoC状态管理、路由导航等为用户提供便捷的充电体验。

基本信息

  • 模块名称: app_charging
  • 路径: oneapp_app_car/app_charging/
  • 依赖: car_services, car_vehicle, clr_charging, basic_modular
  • 主要功能: 充电地图、充电站搜索、订单管理、智能寻桩

目录结构

app_charging/
├── lib/
│   ├── app_charging.dart         # 主导出文件
│   ├── generated/                # 代码生成文件
│   ├── l10n/                     # 国际化文件
│   └── src/                      # 源代码目录
│       ├── app_charging_module.dart # 充电模块配置
│       ├── blocs/                # 状态管理BLoC
│       ├── carfinder/            # 车辆查找功能
│       ├── constants/            # 常量定义
│       ├── pages/                # 页面组件
│       │   └── public_charging/  # 公共充电页面
│       │       ├── charging_map_home_page/      # 充电地图首页
│       │       ├── charging_station_detail_page/ # 充电站详情
│       │       ├── charging_query_order_list_page/ # 订单列表
│       │       ├── charging_report_page/          # 充电报告
│       │       ├── charging_smart_pile_finding_page/ # 智能寻桩
│       │       └── ...           # 其他充电功能页面
│       ├── utils/                # 工具类
│       ├── route_dp.dart         # 路由配置
│       ├── route_export.dart     # 路由导出
│       └── switch_vehicle.dart   # 车辆切换功能
├── assets/                       # 静态资源
└── README.md                     # 项目说明

App Charging - 充电管理模块文档

模块概述

app_charging 是 OneApp 的充电管理核心模块提供完整的电动车充电功能包括充电地图、充电站查找、订单管理、支付结算等全流程充电服务。该模块集成了高德地图服务、BLoC状态管理、路由导航等为用户提供便捷的充电体验。

基本信息

  • 模块名称: app_charging
  • 路径: oneapp_app_car/app_charging/
  • 依赖: car_services, car_vehicle, clr_charging, basic_modular
  • 主要功能: 充电地图、充电站搜索、订单管理、智能寻桩

目录结构

app_charging/
├── lib/
│   ├── app_charging.dart         # 主导出文件
│   ├── generated/                # 代码生成文件
│   ├── l10n/                     # 国际化文件
│   └── src/                      # 源代码目录
│       ├── app_charging_module.dart # 充电模块配置
│       ├── blocs/                # 状态管理BLoC
│       ├── carfinder/            # 车辆查找功能
│       ├── constants/            # 常量定义
│       ├── pages/                # 页面组件
│       │   └── public_charging/  # 公共充电页面
│       │       ├── charging_map_home_page/      # 充电地图首页
│       │       ├── charging_station_detail_page/ # 充电站详情
│       │       ├── charging_query_order_list_page/ # 订单列表
│       │       ├── charging_report_page/          # 充电报告
│       │       ├── charging_smart_pile_finding_page/ # 智能寻桩
│       │       ├── charging_coupon_page/          # 充电优惠券
│       │       ├── charging_power_monitor_page/   # 功率监控
│       │       └── ...           # 其他充电功能页面
│       ├── utils/                # 工具类
│       ├── route_dp.dart         # 路由配置
│       ├── route_export.dart     # 路由导出
│       └── switch_vehicle.dart   # 车辆切换功能
├── assets/                       # 静态资源
└── README.md                     # 项目说明

核心实现

1. 模块主导出文件

文件: lib/app_charging.dart

/// charging pages
library app_charging;

export 'package:car_services/services.dart';
export 'package:car_vehicle/vehicle.dart';

export 'src/app_charging_module.dart';
export 'src/pages/public_charging/charging_map_card/charging_map_card.dart';
export 'src/pages/public_charging/charging_map_home_page/charging_map_home_page.dart';
export 'src/pages/public_charging/charging_query_order_list_page/charging_query_order_list_page.dart';

// 路由键导出
export 'src/route_dp.dart' show ChargingReservationRouteKey;
export 'src/route_dp.dart' show CarChargingCouponRouteKey;
export 'src/route_dp.dart' show ChargingCpoCollectionRouteKey;
export 'src/route_dp.dart' show ChargingDetectiveRouteKey;
export 'src/route_dp.dart' show ChargingMapHomeNonOwnerRouteKey;
export 'src/route_dp.dart' show ChargingMapHomeRouteKey;
export 'src/route_dp.dart' show ChargingPowerMonitorResultRouteKey;
export 'src/route_dp.dart' show ChargingPowerMonitorRouteKey;
export 'src/route_dp.dart' show ChargingPrePaySettingRouteKey;
export 'src/route_dp.dart' show ChargingQueryOrderDetailRouteKey;
export 'src/route_dp.dart' show ChargingQueryOrderListRouteKey;
export 'src/route_dp.dart' show ChargingQueryRatingRouteKey;
export 'src/route_dp.dart' show ChargingReportRouteKey;
export 'src/route_dp.dart' show ChargingSmartPileFindingRouteKey;
export 'src/route_dp.dart' show ChargingStationDetailRouteKey;
export 'src/route_dp.dart' show ChargingStationGuideRouteKey;
export 'src/route_dp.dart' show ChargingVehicleReportRouteKey;
export 'src/route_export.dart';

2. 模块定义与依赖管理

文件: src/app_charging_module.dart

import 'package:basic_logger/basic_logger.dart';
import 'package:basic_modular/modular.dart';
import 'package:basic_modular_route/basic_modular_route.dart';
import 'package:clr_account/account.dart';
import 'package:clr_charging/clr_charging.dart';
import 'package:ui_basic/ui_basic.dart';

import 'constants/module_constant.dart';
import 'route_export.dart';

/// 充电模块定义
class AppChargingModule extends Module with RouteObjProvider, AppLifeCycleListener {
  @override
  List<Bind<Object>> get binds => [];

  @override
  List<Module> get imports => [AccountConModule(), ClrChargingModule()];

  @override
  List<ModularRoute> get routes {
    // 模块首页
    final moduleHome = RouteCenterAPI.routeMetaBy(AppChargingRouteExport.keyModule);
    
    // 充电地图首页
    final chargingMapHome = RouteCenterAPI.routeMetaBy(AppChargingRouteExport.keyChargingMapHome);
    
    // 搜索首页
    final searchHome = RouteCenterAPI.routeMetaBy(AppChargingRouteExport.keySearchHome);
    
    // CPO收藏页面
    final cpoCollection = RouteCenterAPI.routeMetaBy(AppChargingRouteExport.keyChargingCpoCollection);
    
    // 充电站详情页面
    final stationDetailPage = RouteCenterAPI.routeMetaBy(AppChargingRouteExport.keyStationDetailPage);
    
    // 电价页面
    final electricPricePage = RouteCenterAPI.routeMetaBy(AppChargingRouteExport.keyStationElectricPricePage);
    
    return [
      ChildRoute<dynamic>(moduleHome.path, child: (_, args) => moduleHome.provider(args).as()),
      ChildRoute<dynamic>(chargingMapHome.path, child: (_, args) => chargingMapHome.provider(args).as()),
      ChildRoute<dynamic>(searchHome.path, child: (_, args) => searchHome.provider(args).as()),
      ChildRoute<dynamic>(cpoCollection.path, child: (_, args) => cpoCollection.provider(args).as()),
      ChildRoute<dynamic>(stationDetailPage.path, child: (_, args) => stationDetailPage.provider(args).as()),
      ChildRoute<dynamic>(electricPricePage.path, child: (_, args) => electricPricePage.provider(args).as()),
      // 更多路由配置...
    ];
  }
}

3. 路由导出管理

文件: src/route_export.dart

import 'dart:convert';

import 'package:amap_flutter_base/amap_flutter_base.dart';
import 'package:basic_logger/basic_logger.dart';
import 'package:basic_modular/modular.dart';
import 'package:clr_charging/clr_charging.dart';
import 'package:clr_geo/clr_geo.dart';

import 'app_charging_module.dart';
import 'pages/public_charging/charging_map_home_page/charging_map_home_page.dart';
import 'pages/public_charging/charging_station_detail_page/charging_station_detail_page.dart';
import 'pages/public_charging/charging_query_order_list_page/charging_query_order_list_page.dart';
import 'pages/public_charging/charging_smart_pile_finding_page/charging_smart_pile_finding_page.dart';
// ... 更多页面导入

/// app_charging的路由管理
class AppChargingRouteExport implements RouteExporter {
  // 路由键常量定义
  static const String keyModule = 'charging';
  static const String keyChargingMapHome = 'charging.map_home';
  static const String keySearchHome = 'charging.search_home';
  static const String keyChargingCpoCollection = 'charging.cpo_collection';
  static const String keyStationDetailPage = 'charging.station_detail';
  static const String keyStationElectricPricePage = 'charging.electric_price';
  static const String keyQueryOrderListPage = 'charging.order_list';
  static const String keySmartPileFinding = 'charging.smart_pile_finding';
  static const String keyChargingReport = 'charging.report';
  static const String keyPowerMonitor = 'charging.power_monitor';
  // ... 更多路由键定义

  @override
  List<RouteMeta> exportRoutes() {
    // 模块根路由
    final r0 = RouteMeta(keyModule, '/charging', (args) => AppChargingModule(), null);
    
    // 充电地图首页
    final r1 = RouteMeta(
      keyChargingMapHome,
      '/map_home',
      (args) => ChargingMapHomePage(args.data['vin'] as String?),
      r0,
    );
    
    // 充电站详情页面
    final r2 = RouteMeta(
      keyStationDetailPage,
      '/station_detail',
      (args) => ChargingStationDetailPage(
        stationID: args.data['stationID'] as String,
        chargingVin: args.data['chargingVin'] as String?,
      ),
      r0,
    );
    
    // 智能寻桩页面
    final r3 = RouteMeta(
      keySmartPileFinding,
      '/smart_pile_finding',
      (args) => ChargingSmartPileFindingPage(
        vin: args.data['vin'] as String,
      ),
      r0,
    );
    
    // 订单列表页面
    final r4 = RouteMeta(
      keyQueryOrderListPage,
      '/order_list',
      (args) => ChargingQueryOrderListPage(
        vin: args.data['vin'] as String,
      ),
      r0,
    );
    
    return [r0, r1, r2, r3, r4];
  }
}

核心功能模块

1. 充电地图首页

文件: pages/public_charging/charging_map_home_page/charging_map_home_page.dart

import 'package:flutter/material.dart';
import 'package:amap_flutter_map/amap_flutter_map.dart';
import 'package:basic_modular/modular.dart';

/// 充电地图首页
class ChargingMapHomePage extends StatefulWidget {
  const ChargingMapHomePage(this.vin, {Key? key}) : super(key: key);
  
  final String? vin;

  @override
  State<ChargingMapHomePage> createState() => _ChargingMapHomePageState();
}

class _ChargingMapHomePageState extends State<ChargingMapHomePage> {
  AMapController? _mapController;
  List<ChargingStation> _chargingStations = [];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('充电地图'),
        actions: [
          IconButton(
            icon: Icon(Icons.search),
            onPressed: _openSearch,
          ),
          IconButton(
            icon: Icon(Icons.filter_list),
            onPressed: _openFilter,
          ),
        ],
      ),
      body: Stack(
        children: [
          // 地图组件
          AMapWidget(
            onMapCreated: _onMapCreated,
            markers: Set<Marker>.from(_buildMarkers()),
          ),
          
          // 功能按钮区域
          Positioned(
            bottom: 100,
            right: 16,
            child: Column(
              children: [
                FloatingActionButton(
                  heroTag: "locate",
                  onPressed: _locateUser,
                  child: Icon(Icons.my_location),
                ),
                SizedBox(height: 10),
                FloatingActionButton(
                  heroTag: "smart_find",
                  onPressed: _smartPileFinding,
                  child: Icon(Icons.electric_bolt),
                ),
              ],
            ),
          ),
          
          // 底部信息卡片
          _buildBottomSheet(),
        ],
      ),
    );
  }
  
  void _onMapCreated(AMapController controller) {
    _mapController = controller;
    _loadChargingStations();
  }
  
  List<Marker> _buildMarkers() {
    return _chargingStations.map((station) {
      return Marker(
        markerId: MarkerId(station.id),
        position: LatLng(station.latitude, station.longitude),
        infoWindow: InfoWindow(title: station.name),
        onTap: () => _showStationDetail(station),
      );
    }).toList();
  }
  
  void _loadChargingStations() {
    // 加载充电站数据
  }
  
  void _openSearch() {
    Modular.to.pushNamed('/charging/search_home');
  }
  
  void _openFilter() {
    Modular.to.pushNamed('/charging/filter');
  }
  
  void _locateUser() {
    // 定位到用户位置
  }
  
  void _smartPileFinding() {
    if (widget.vin != null) {
      Modular.to.pushNamed('/charging/smart_pile_finding', arguments: {
        'vin': widget.vin,
      });
    }
  }
  
  void _showStationDetail(ChargingStation station) {
    Modular.to.pushNamed('/charging/station_detail', arguments: {
      'stationID': station.id,
      'chargingVin': widget.vin,
    });
  }
  
  Widget _buildBottomSheet() {
    return Positioned(
      bottom: 0,
      left: 0,
      right: 0,
      child: Container(
        height: 80,
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
          boxShadow: [
            BoxShadow(
              color: Colors.black.withOpacity(0.1),
              blurRadius: 8,
              offset: Offset(0, -2),
            ),
          ],
        ),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            _buildBottomAction(Icons.list, '订单', _openOrderList),
            _buildBottomAction(Icons.assessment, '报告', _openReport),
            _buildBottomAction(Icons.settings, '设置', _openSettings),
          ],
        ),
      ),
    );
  }
  
  Widget _buildBottomAction(IconData icon, String label, VoidCallback onTap) {
    return InkWell(
      onTap: onTap,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Icon(icon, color: Colors.blue),
          SizedBox(height: 4),
          Text(label, style: TextStyle(fontSize: 12)),
        ],
      ),
    );
  }
  
  void _openOrderList() {
    if (widget.vin != null) {
      Modular.to.pushNamed('/charging/order_list', arguments: {
        'vin': widget.vin,
      });
    }
  }
  
  void _openReport() {
    if (widget.vin != null) {
      Modular.to.pushNamed('/charging/report', arguments: {
        'vin': widget.vin,
      });
    }
  }
  
  void _openSettings() {
    Modular.to.pushNamed('/charging/settings');
  }
}

// 充电站数据模型
class ChargingStation {
  final String id;
  final String name;
  final double latitude;
  final double longitude;
  final int totalPiles;
  final int availablePiles;
  
  ChargingStation({
    required this.id,
    required this.name,
    required this.latitude,
    required this.longitude,
    required this.totalPiles,
    required this.availablePiles,
  });
}

2. 充电站详情页面

/// 充电站详情页面
class ChargingStationDetailPage extends StatefulWidget {
  const ChargingStationDetailPage({
    Key? key,
    required this.stationID,
    this.chargingVin,
  }) : super(key: key);
  
  final String stationID;
  final String? chargingVin;

  @override
  State<ChargingStationDetailPage> createState() => _ChargingStationDetailPageState();
}

class _ChargingStationDetailPageState extends State<ChargingStationDetailPage> {
  ChargingStationDetail? _stationDetail;
  bool _isLoading = true;

  @override
  void initState() {
    super.initState();
    _loadStationDetail();
  }

  @override
  Widget build(BuildContext context) {
    if (_isLoading) {
      return Scaffold(
        appBar: AppBar(title: Text('充电站详情')),
        body: Center(child: CircularProgressIndicator()),
      );
    }

    if (_stationDetail == null) {
      return Scaffold(
        appBar: AppBar(title: Text('充电站详情')),
        body: Center(child: Text('加载失败')),
      );
    }

    return Scaffold(
      appBar: AppBar(
        title: Text(_stationDetail!.name),
        actions: [
          IconButton(
            icon: Icon(Icons.share),
            onPressed: _shareStation,
          ),
        ],
      ),
      body: SingleChildScrollView(
        child: Column(
          children: [
            // 充电站基本信息
            _buildStationInfo(),
            
            // 充电桩列表
            _buildChargingPilesList(),
            
            // 服务设施
            _buildFacilities(),
            
            // 电价信息
            _buildPriceInfo(),
            
            // 评价与评论
            _buildRatingsSection(),
          ],
        ),
      ),
      bottomNavigationBar: Container(
        padding: EdgeInsets.all(16),
        child: Row(
          children: [
            Expanded(
              child: ElevatedButton(
                onPressed: _navigateToStation,
                child: Text('导航'),
              ),
            ),
            SizedBox(width: 16),
            Expanded(
              child: ElevatedButton(
                onPressed: _bookChargingPile,
                style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.green,
                ),
                child: Text('预约充电'),
              ),
            ),
          ],
        ),
      ),
    );
  }
  
  Widget _buildStationInfo() {
    return Container(
      padding: EdgeInsets.all(16),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(_stationDetail!.name, style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
          SizedBox(height: 8),
          Text(_stationDetail!.address, style: TextStyle(color: Colors.grey[600])),
          SizedBox(height: 16),
          Row(
            children: [
              _buildInfoChip('总桩数', '${_stationDetail!.totalPiles}'),
              SizedBox(width: 16),
              _buildInfoChip('可用桩数', '${_stationDetail!.availablePiles}'),
            ],
          ),
        ],
      ),
    );
  }
  
  Widget _buildInfoChip(String label, String value) {
    return Container(
      padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6),
      decoration: BoxDecoration(
        color: Colors.blue.withOpacity(0.1),
        borderRadius: BorderRadius.circular(16),
      ),
      child: Text('$label: $value', style: TextStyle(color: Colors.blue)),
    );
  }
  
  void _loadStationDetail() {
    // 加载充电站详情数据
    Future.delayed(Duration(seconds: 1), () {
      setState(() {
        _stationDetail = ChargingStationDetail(
          id: widget.stationID,
          name: '示例充电站',
          address: '示例地址',
          totalPiles: 10,
          availablePiles: 6,
        );
        _isLoading = false;
      });
    });
  }
  
  void _navigateToStation() {
    Modular.to.pushNamed('/charging/station_guide', arguments: {
      'stationID': widget.stationID,
    });
  }
  
  void _bookChargingPile() {
    Modular.to.pushNamed('/charging/reservation', arguments: {
      'stationID': widget.stationID,
      'vin': widget.chargingVin,
    });
  }
}

// 充电站详情数据模型
class ChargingStationDetail {
  final String id;
  final String name;
  final String address;
  final int totalPiles;
  final int availablePiles;
  
  ChargingStationDetail({
    required this.id,
    required this.name,
    required this.address,
    required this.totalPiles,
    required this.availablePiles,
  });
}

3. 智能寻桩页面

/// 智能寻桩页面
class ChargingSmartPileFindingPage extends StatefulWidget {
  const ChargingSmartPileFindingPage({
    Key? key,
    required this.vin,
  }) : super(key: key);
  
  final String vin;

  @override
  State<ChargingSmartPileFindingPage> createState() => _ChargingSmartPileFindingPageState();
}

class _ChargingSmartPileFindingPageState extends State<ChargingSmartPileFindingPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('智能寻桩')),
      body: Column(
        children: [
          // 车辆信息卡片
          _buildVehicleInfoCard(),
          
          // 推荐充电站列表
          Expanded(
            child: ListView.builder(
              itemCount: _recommendedStations.length,
              itemBuilder: (context, index) {
                final station = _recommendedStations[index];
                return _buildStationRecommendCard(station);
              },
            ),
          ),
        ],
      ),
    );
  }
  
  Widget _buildVehicleInfoCard() {
    return Container(
      margin: EdgeInsets.all(16),
      padding: EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(12),
        boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.1), blurRadius: 4)],
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text('当前车辆', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
          SizedBox(height: 8),
          Text('VIN: ${widget.vin}'),
          Text('当前电量: 30%'),
          Text('续航里程: 120km'),
        ],
      ),
    );
  }
  
  Widget _buildStationRecommendCard(RecommendedStation station) {
    return Container(
      margin: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
      child: Card(
        child: ListTile(
          title: Text(station.name),
          subtitle: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text('距离: ${station.distance}km'),
              Text('可用桩数: ${station.availablePiles}'),
              Text('预计费用: ¥${station.estimatedCost}'),
            ],
          ),
          trailing: ElevatedButton(
            onPressed: () => _selectStation(station),
            child: Text('选择'),
          ),
        ),
      ),
    );
  }
  
  void _selectStation(RecommendedStation station) {
    Modular.to.pushNamed('/charging/station_detail', arguments: {
      'stationID': station.id,
      'chargingVin': widget.vin,
    });
  }
}

// 推荐充电站数据模型
class RecommendedStation {
  final String id;
  final String name;
  final double distance;
  final int availablePiles;
  final double estimatedCost;
  
  RecommendedStation({
    required this.id,
    required this.name,
    required this.distance,
    required this.availablePiles,
    required this.estimatedCost,
  });
}

状态管理 (BLoC)

充电地图状态管理

// 充电地图状态管理
class ChargingMapHomeBloc extends Bloc<ChargingMapHomeEvent, ChargingMapHomeState> {
  final ChargingService _chargingService;
  
  ChargingMapHomeBloc(this._chargingService) : super(ChargingMapHomeInitial()) {
    on<LoadChargingStationsEvent>(_onLoadChargingStations);
    on<FilterStationsEvent>(_onFilterStations);
    on<SearchStationsEvent>(_onSearchStations);
  }
  
  Future<void> _onLoadChargingStations(
    LoadChargingStationsEvent event,
    Emitter<ChargingMapHomeState> emit,
  ) async {
    emit(ChargingMapHomeLoading());
    
    try {
      final stations = await _chargingService.getNearbyStations(
        latitude: event.latitude,
        longitude: event.longitude,
        radius: event.radius,
      );
      
      emit(ChargingMapHomeLoaded(stations));
    } catch (e) {
      emit(ChargingMapHomeError(e.toString()));
    }
  }
  
  Future<void> _onFilterStations(
    FilterStationsEvent event,
    Emitter<ChargingMapHomeState> emit,
  ) async {
    if (state is ChargingMapHomeLoaded) {
      final currentState = state as ChargingMapHomeLoaded;
      final filteredStations = _applyFilter(currentState.stations, event.filter);
      emit(ChargingMapHomeLoaded(filteredStations));
    }
  }
  
  List<ChargingStation> _applyFilter(List<ChargingStation> stations, StationFilter filter) {
    return stations.where((station) {
      if (filter.onlyAvailable && station.availablePiles == 0) return false;
      if (filter.maxDistance != null && station.distance > filter.maxDistance!) return false;
      return true;
    }).toList();
  }
}

// 事件定义
abstract class ChargingMapHomeEvent {}

class LoadChargingStationsEvent extends ChargingMapHomeEvent {
  final double latitude;
  final double longitude;
  final double radius;
  
  LoadChargingStationsEvent(this.latitude, this.longitude, this.radius);
}

class FilterStationsEvent extends ChargingMapHomeEvent {
  final StationFilter filter;
  FilterStationsEvent(this.filter);
}

// 状态定义
abstract class ChargingMapHomeState {}

class ChargingMapHomeInitial extends ChargingMapHomeState {}

class ChargingMapHomeLoading extends ChargingMapHomeState {}

class ChargingMapHomeLoaded extends ChargingMapHomeState {
  final List<ChargingStation> stations;
  ChargingMapHomeLoaded(this.stations);
}

class ChargingMapHomeError extends ChargingMapHomeState {
  final String message;
  ChargingMapHomeError(this.message);
}

// 过滤器模型
class StationFilter {
  final bool onlyAvailable;
  final double? maxDistance;
  final List<String>? supportedConnectors;
  
  StationFilter({
    this.onlyAvailable = false,
    this.maxDistance,
    this.supportedConnectors,
  });
}

依赖管理

核心依赖

  • clr_charging: 充电服务SDK
  • car_services: 车辆服务
  • car_vehicle: 车辆管理
  • amap_flutter_map: 高德地图

框架依赖

  • basic_modular: 模块化框架
  • basic_modular_route: 路由管理
  • basic_logger: 日志服务
  • ui_basic: 基础UI组件

账户与支付

  • clr_account: 账户管理
  • clr_geo: 地理位置服务

最佳实践

1. 代码组织

  • 按业务功能模块化组织
  • 统一的路由管理和页面导航
  • 清晰的状态管理模式

2. 用户体验

  • 地图加载优化和缓存策略
  • 实时充电桩状态更新
  • 智能推荐算法

3. 性能优化

  • 地图资源合理加载释放
  • 充电站数据分页加载
  • 网络请求优化和重试机制