# vend-mobile-flutter **Repository Path**: vend_public/vend-mobile-flutter ## Basic Information - **Project Name**: vend-mobile-flutter - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-29 - **Last Updated**: 2026-09-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # vend-mobile-flutter Glabal Auto Vending - Flutter mobile client. This project is the Flutter port of the existing **vend-mobile-uniapp** app. It shares the same backend API as vend_manage_web (POST-only envelope `{ code, data, msg }`), and mirrors the uniapp design system (colors, spacing, bottom-tab structure). ## 1. Verified status | Check | Result | | --- | --- | | Flutter SDK | 3.47.5 stable (at D:\1_tools\32_Flutter_local\flutter) | | flutter pub get | OK - 105 deps resolved | | flutter analyze | OK - No issues found | | flutter test | OK - 2 tests passed | | flutter build web --release | OK - Built build/web/ | | Android SDK | MISSING - required for `flutter build apk` | | Chrome (web run) | available - `flutter run -d chrome` works immediately | ## 2. Run ```powershell $env:Path = "D:\1_tools\32_Flutter_local\flutter\bin;" + $env:Path cd D:\2_tzh_space\vend_space\vend-mobile-flutter # Fastest way to see the UI - in Chrome: flutter run -d chrome # Android device / emulator (after installing Android Studio + accepting licenses): flutter run --dart-define=API_BASE=http://192.168.x.x:9090 # Release APK: flutter build apk --release --dart-define=API_BASE=https://api.ezvend.example.com ``` Default API_BASE is http://10.0.2.2:9090 (Android emulator -> host loopback). For physical devices, override with --dart-define=API_BASE=... ## 3. Architecture lib/ main.dart - runApp entry bootstrap.dart - composition root: StorageService / ApiClient / AuthService app.dart - MaterialApp.router config/app_config.dart - API base, storage keys, package id (mirrors utils/request.js) theme/ app_colors.dart - 1:1 port of uni.scss tokens app_theme.dart - ThemeData + card shadows router/app_router.dart - go_router: splash -> login -> ShellRoute(5 tabs) services/ storage_service.dart - shared_preferences + flutter_secure_storage (pre-warmed) api_client.dart - Dio: bearer, nonce/trace headers, 401 refresh auth_service.dart - login/logout, token persistence models/ auth.dart - AuthPayload / AuthUser (normalizeAuthPayload port) device.dart - DeviceSummary / DashboardStats / OrderSummary widgets/ - Vend* shared components features/ splash/ - auto-redirect by token presence auth/login_page.dart shell/main_shell.dart - bottom tab bar (mirrors VendTabBar.vue) dashboard/ orders/ support/ replenish/ settings/ ### Networking - Dio interceptor injects Authorization, X-Request-Nonce, X-Request-Timestamp, X-Trace-Id - matching vend-mobile-uniapp/utils/request.js. - Envelope { code, data, msg }: code==200 unwraps data, otherwise throws ApiException. - On 401: POST /auth/oauth2/refresh once, retry original; repeated failures -> login. ### Not yet ported: request body encryption vend-mobile-uniapp/utils/requestEncryption.js encrypts request bodies. The Dart ApiClient currently sends plaintext JSON. If the backend enforces encryption, port that module into ApiClient._maybeEncrypt (hook documented inline). ## 4. Parity with vend-mobile-uniapp Implemented tabs: | uniapp route | Flutter location | | ----------------------------- | ----------------------------------------- | | pages/index/index (splash) | features/splash/splash_page.dart | | pages/index/index (login) | features/auth/login_page.dart | | pages/dashboard/index | features/dashboard/dashboard_page.dart | | pages/orders/index | features/orders/orders_page.dart | | pages/support/index | features/support/support_page.dart | | pages/replenish/index | features/replenish/replenish_page.dart | | pages/settings/index | features/settings/settings_page.dart | | components/VendTabBar.vue | features/shell/main_shell.dart | | components/VendNavbar.vue | widgets/vend_navbar.dart | | components/VendStatCard.vue | widgets/vend_stat_card.dart | | components/VendStatusBadge.vue| widgets/vend_status_badge.dart | | components/VendEmptyState.vue | widgets/vend_empty_state.dart | | components/VendSearchBar.vue | widgets/vend_search_bar.dart | Remaining pages (to be ported incrementally): device-detail, device-activation, device-health, abnormal-devices, out-of-stock, groups, geofence(+edit), order-detail, abnormal-orders(+detail), after-sales(+detail), refund-detail, replenish-detail, replenish-plans, inventory(+check+detail), products(+categories+detail+new-product), tax-templates, ad-management, payment, reports(+sales-detail), reconciliation, work-orders, cargo-optimization, ota-upgrade, notifications, alert-center, global-search, profile, more-settings, change-password, personnel, audit-records, blacklist, contact-support, operation-guide ## 5. Design tokens (ported 1:1 from uni.scss) brand #0F6BFF | accent #00C48C | bg #F2F5FA | bg-card #FFFFFF text #1A1D28 | text-second #6B7280 | danger #EF3F4A | warning #F59E0B | success #10B981 ## 6. Package identity Android applicationId / iOS bundleId: com.grabot.ezvend Version: 2.0.0 (200) Permissions: INTERNET, CAMERA, LOCATION, NOTIFICATIONS, VIBRATE