# 运维管理台(Ops Console) 设备/系统运维管理台移动端,覆盖 **Android / iOS / HarmonyOS (OpenHarmony)** 三端,共用同一套 `lib/` Dart 代码。 默认对接真实「爱视后台」(PHP/CodeIgniter),同时保留 mock 开关供无后端时演示。 ## 技术栈 - **Flutter 3.22+**(Dart 3) - **go_router** —— 声明式路由(登录重定向、底部导航多分支) - **flutter_riverpod** —— 状态管理(登录态 / 设备与告警数据 / 主题模式) - **dio** —— HTTP 客户端(Bearer 鉴权 + 统一信封解包 + 401 刷新重试;可选 mock 拦截器) - **intl** —— 日期时间格式化 ## API 配置(lib/utils/constants.dart) | 常量 | 默认值 | 说明 | | ------------ | --------------------- | ------------------------------------------------ | | `useMock` | `false` | `false` 对接真实后端;`true` 由 MockInterceptor 本地返回示例数据 | | `apiBaseUrl` | `http://58.220.83.58` | 真实后端 origin | | `apiPrefix` | `/api` | 接口统一前缀;最终 URL = `apiBaseUrl + /api + path` | ## HTTP 通用规则 - **鉴权**:请求头 `Authorization: Bearer `,不使用 Cookie。 - **Content-Type**:`application/json; charset=utf-8`。 - **防缓存**:GET 参数与 POST body 均自动附加 `t` = 毫秒时间戳。 - **统一响应**:`{ code:int, msg:string, data:T }`,成功码 `code ∈ {0, 200}`, 由 `ApiInterceptor` 自动解包(service 层拿到的即 `data`);非成功码抛出 `ApiException(code, msg)`。 - **401 处理**:业务 `code=401` 或 HTTP 401 时,自动用 refreshToken 调 `POST /api/sys/refresh {refreshToken}` 换新 token 并**原样重试一次**; 仍失败则清空登录态并跳转登录页(经 `ApiClient.onUnauthorized` → `authProvider` → 路由 redirect)。 ## 真实接口清单 | 接口 | 方法 | 说明 | | ------------------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------------- | | `/api/sys/login` | POST | 登录,body `{username,password,captcha,uuid}` → `{token,expire,refreshToken,refreshExpire,orgId,orgType,superAdmin,roleNames}` | | `/api/sys/refresh` | POST | 刷新令牌,body `{refreshToken}` → `{token,expire,refreshToken,refreshExpire}`(拦截器自动调用) | | `/api/sys/logout` | POST | 登出 | | `/api/sys/user/info` | GET | 当前用户信息(登录后自动拉取补充显示名) | | `/api/device/info/list` | GET | 设备列表,params `page,limit,status,mac,deviceSn,deviceUid,groupId,storeOrgId`;响应 `{list,totalCount}` / `{page:{list,totalCount}}` / 直接数组三种形态均兼容 | | `/api/device/info/info/{id}` | GET | 设备详情 | | `/api/device/command/sendByMac` | POST | 按 MAC 下发指令,body `{mac,command,data}` | | `/api/device/command/sendByOrg` | POST | 按组织批量下发指令,body `{orgId,command,data}` | 指令 `command` 取值(见 `DeviceCommand` 常量):`powerOff` / `reboot` / `screenshot` / `themeUpdate` / `versionUpdate` / `marqueeUpdate` / `weatherUpdate` / `mediaZoneVol` / `defaultVol` / `themeClear` / `cacheClear` / `storeExpire` / `storeDisable` / `passwordUpdate` / `worldAd`。 **指令下发 UI 属下一轮迭代**:当前仅实现 `DeviceService.sendCommandByMac/sendCommandByOrg` service 方法,界面未接入按钮。 ## 告警推导(real 模式) 真实后端无 alerts 端点。real 模式下告警由设备列表推导: `offline → critical`(设备离线)、`warning → warning`(设备指标异常), 在线设备映射为 `info` 级别但不产生告警条目。mock 模式仍使用内置示例告警。 ## ⚠️ 权威构建路径(必读) 本仓库中的 `android/`、`ios/`、`ohos/` 原生壳是**手写的参考起点**,已包含可资源编译的最小配置 (图标、启动页、storyboard、媒体占位资源等)。但以下内容**只能由 Flutter 工具链生成,无法手写**: | 生成物 | 所属平台 | 生成命令 | | -------------------------------------------------------------------- | --------- | ------------------------------------------ | | `gradlew` / `gradle-wrapper.jar` / `local.properties` | Android | `flutter create` | | `Runner.xcodeproj` / `Generated.xcconfig` / `AppFrameworkInfo.plist` | iOS | `flutter create` | | `hvigorfile.ts` / `oh_modules` 依赖链接 | HarmonyOS | `flutter create --platforms=ohos`(鸿蒙分支工具链) | **因此首次构建前,必须在本机 Flutter 环境执行一次 `flutter create` 补齐工具链生成物:** ```bash cd ops-console # 一次性补齐三端原生壳的缺失文件(不会覆盖已存在的自定义文件) flutter create --platforms=android,ios,ohos . ``` > 注意: > > 1. `flutter create` 只补缺、不覆盖已有文件,仓库中已定制的 > `android/app/build.gradle`(applicationId、JDK 17)、`AndroidManifest.xml`(应用名「运维管理台」) > 会被保留。 > 2. HarmonyOS 端需使用 **Flutter OpenHarmony SDK**(`flutter-flutter` 鸿蒙分支)执行上述命令; > 标准 Flutter SDK 不认识 `--platforms=ohos`。 ## 环境要求 | 项目 | 要求 | | ----------- | --------------------------------------------------------------- | | Flutter SDK | 3.22 及以上(`flutter --version` 确认,Dart >= 3.4) | | Android | Android Studio + Android SDK(API 21+),JDK 17 | | iOS | macOS + Xcode 15+、CocoaPods | | HarmonyOS | DevEco Studio + Flutter OpenHarmony SDK(`flutter-flutter` 鸿蒙分支) | ## 构建命令 ```bash # 0. 首次:补齐全端工具链生成物 + 安装依赖 flutter create --platforms=android,ios,ohos . flutter pub get ``` ### Android ```bash flutter run # 连接设备或模拟器后直接运行 flutter build apk # 打包 APK(debug 签名,正式发布需配置签名) ``` ### iOS(需 macOS + Xcode) ```bash flutter pub get cd ios && pod install && cd .. # 安装 CocoaPods 依赖 flutter run flutter build ios ``` ### HarmonyOS (OpenHarmony) 需使用 **Flutter OpenHarmony SDK**(鸿蒙分支的 flutter 工具链): ```bash # 补齐/校验 ohos 平台工程 flutter create --platforms=ohos . # 运行(连接鸿蒙设备/模拟器) flutter run # 构建 hap/app 包 flutter build ohos ``` 也可在 DevEco Studio 中打开 `ohos/` 目录进行签名配置与构建(`build-profile.json5` 中的 `signingConfigs` 为空,需在 DevEco 中配置签名后才能出 release 包)。 ## 目录结构 ``` ops-console/ ├── pubspec.yaml # 依赖声明 ├── analysis_options.yaml # 静态分析规则(flutter_lints) ├── lib/ │ ├── main.dart # 入口:ProviderScope + MaterialApp.router │ ├── app/ │ │ ├── theme.dart # 浅色/深色主题(主色科技蓝 #2E7DFF) │ │ └── router.dart # go_router 路由表 + 未登录重定向 │ ├── utils/ │ │ ├── constants.dart # 全局常量(useMock / apiBaseUrl / mock 账号等) │ │ └── formatters.dart # 时间/百分比/字节/运行时长格式化 │ ├── models/ │ │ ├── device.dart # Device + DeviceStatus + DeviceMetrics + DeviceCommand │ │ ├── alert.dart # Alert + AlertLevel(critical/warning/info) │ │ └── user.dart # User │ ├── services/ │ │ ├── api_client.dart # Dio 单例 + ApiInterceptor(Bearer/t/解包/401重试) │ │ │ # + MockInterceptor(useMock=true 时)+ TokenStore(内存态) │ │ ├── auth_service.dart # 登录/登出/用户信息(真实接口) │ │ └── device_service.dart # 设备列表/详情/指令/告警推导 │ ├── providers/ │ │ ├── auth_provider.dart # 登录态(authProvider,注册 onUnauthorized) │ │ ├── devices_provider.dart # 设备/告警数据(devicesProvider 等) │ │ └── theme_provider.dart # 主题模式(默认深色) │ ├── widgets/ │ │ ├── status_chip.dart # 状态标签 │ │ ├── metric_card.dart # 指标卡片 │ │ ├── device_list_tile.dart # 设备列表项 │ │ └── app_bottom_nav.dart # 底部导航(设备/告警/设置) │ └── screens/ │ ├── login/login_page.dart # 登录页 │ ├── home/device_list_page.dart # 首页:搜索 + 设备列表 │ ├── home/device_detail_page.dart # 设备详情:指标卡(real 模式显示 “—”) │ ├── alerts/alerts_page.dart # 告警列表 │ └── profile/settings_page.dart # 设置:主题/语言占位/关于/退出 ├── android/ # Android 壳(Gradle + Manifest + res 资源) ├── ios/ # iOS 壳(Runner + Flutter xcconfig + Podfile) └── ohos/ # OpenHarmony 壳(stage 模型) ``` ## 路由表 | 路径 | 页面 | 说明 | | ------------- | ---- | ------------- | | `/login` | 登录页 | 未登录时自动重定向到此 | | `/` | 设备列表 | 底部导航第 1 个 tab | | `/device/:id` | 设备详情 | 从设备列表进入 | | `/alerts` | 告警中心 | 底部导航第 2 个 tab | | `/settings` | 设置 | 底部导航第 3 个 tab | ## Mock 数据说明 - 将 `AppConstants.useMock` 改为 `true` 即进入演示模式:所有请求由 `MockInterceptor` 本地拦截,返回与真实后端一致的 `{code,msg,data}` 信封 (5 台设备含示例运行指标、5 条示例告警),不发起真实网络请求。 - mock 演示登录账号:`admin` / `123456`。 - 真实模式(默认)下请使用后端分配的账号登录。 ## 主题 - 默认 **深色** 主题,主色科技蓝 `#2E7DFF`。 - 在「设置 → 主题模式」可切换 深色 / 浅色 / 跟随系统。 ## 已知限制 1. **token 仅内存态**:为规避鸿蒙端插件兼容问题未引入 shared_preferences, 应用重启后需重新登录(持久化属后续迭代,需评估鸿蒙插件支持度)。 2. **验证码占位**:登录接口的 `captcha/uuid` 字段当前传空串(登录页 UI 无验证码输入, 属下一轮迭代);若后端强制校验验证码,需先补 UI。 3. **运行指标缺失**:真实后端不提供 CPU/内存/磁盘/网络指标,real 模式设备详情页 指标卡显示 “—”;`useMock=true` 时显示示例指标。 4. **指令下发 UI 未接入**:service 层已实现,界面按钮属下一轮迭代。 5. **图标为占位资源**(Android 自适应图标 / iOS 空 AppIcon / ohos 1x1 PNG),正式发布前请替换。 6. `android/gradlew`、`ios/Runner.xcodeproj`、`ohos/hvigorfile.ts` 等工具链生成物未入库, 按上文「权威构建路径」执行 `flutter create` 后自动生成。