feat: 完成 Flutter 版智能电网 IoT 管理应用初始化搭建

This commit is contained in:
andyesfly committed 2026-10-02 17:21:53 +08:00
commit f61b7bf90b
120 files changed
+15229

No files matched your search

@@ -0,0 +1,22 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../core/network/api_client.dart';
import '../../../core/network/api_response.dart';
import '../../../core/providers.dart';
import 'dashboard_models.dart';
final dashboardApiProvider = Provider<DashboardApi>(
(ref) => DashboardApi(ref.watch(apiClientProvider)),
);
/// 工作台统计接口,对应 uni-app 版 `api/dashboard.ts`。
class DashboardApi {
DashboardApi(this._client);
final ApiClient _client;
Future<ApiResponse<DashboardStats>> stats() => _client.get<DashboardStats>(
'/dashboard/stats',
parse: (d) => DashboardStats.fromJson((d as Map).cast<String, dynamic>()),
);
}
@@ -0,0 +1,159 @@
import '../../../core/utils/id_util.dart';
/// 名称/数值二元组(勘察状态分布、模块统计、客户状态分布)。
class NameValue {
const NameValue({required this.name, required this.value});
final String name;
final int value;
factory NameValue.fromJson(Map<String, dynamic> json) => NameValue(
name: json['name'] as String? ?? '',
value: (json['value'] as num?)?.toInt() ?? 0,
);
}
/// 近期勘察派单流水。
class DashboardSurveyItem {
const DashboardSurveyItem({
required this.id,
required this.orderNo,
required this.customerName,
required this.locale,
required this.owner,
required this.status,
required this.time,
});
final int id;
final String orderNo;
final String customerName;
final String locale;
final String owner;
/// 0 待指派 / 1 现场勘察中 / 2 待技术复核 / 3 已归档 / 5 已取消
final int status;
final String time;
factory DashboardSurveyItem.fromJson(Map<String, dynamic> json) =>
DashboardSurveyItem(
id: toIntOr(json['id'], 0),
orderNo: json['orderNo'] as String? ?? '',
customerName: json['customerName'] as String? ?? '',
locale: json['locale'] as String? ?? '',
owner: json['owner'] as String? ?? '',
status: toIntOr(json['status'], 0),
time: json['time'] as String? ?? '',
);
}
/// 智电工程推进看板(contract 聚合)。
class DashboardProjectItem {
const DashboardProjectItem({
required this.id,
required this.customerName,
required this.amount,
required this.stage,
required this.stageLabel,
required this.progress,
required this.owner,
required this.desc,
required this.orderNo,
});
final int id;
final String customerName;
final num amount;
final int stage;
final String stageLabel;
final int progress;
final String owner;
final String desc;
final String orderNo;
factory DashboardProjectItem.fromJson(Map<String, dynamic> json) =>
DashboardProjectItem(
id: toIntOr(json['id'], 0),
customerName: json['customerName'] as String? ?? '',
amount: (json['amount'] as num?) ?? 0,
stage: toIntOr(json['stage'], 0),
stageLabel: json['stageLabel'] as String? ?? '',
progress: toIntOr(json['progress'], 0),
owner: json['owner'] as String? ?? '',
desc: json['desc'] as String? ?? '',
orderNo: json['orderNo'] as String? ?? '',
);
}
/// `/api/dashboard/stats` 真实返回体(与后端 dashboard.service.ts 对齐)。
class DashboardStats {
const DashboardStats({
required this.customerTotal,
required this.customerMonthlyNew,
required this.contractTotal,
required this.contractYearAmount,
required this.surveyPending,
required this.surveyTotal,
required this.visitMonthly,
required this.visitTotal,
required this.planTotal,
required this.acceptTotal,
required this.surveyByStatus,
required this.modules,
required this.trend,
required this.customerStatus,
required this.customerSignRate,
required this.surveyList,
required this.projects,
});
final int customerTotal;
final int customerMonthlyNew;
final int contractTotal;
final num contractYearAmount;
final int surveyPending;
final int surveyTotal;
final int visitMonthly;
final int visitTotal;
final int planTotal;
final int acceptTotal;
final List<NameValue> surveyByStatus;
final List<NameValue> modules;
final List<NameValue> customerStatus;
final num customerSignRate;
final List<DashboardSurveyItem> surveyList;
final List<DashboardProjectItem> projects;
/// 趋势项字段为 `{ date, customers, contracts }`,App 端暂未使用,保留原始结构。
final List<Map<String, dynamic>> trend;
factory DashboardStats.fromJson(Map<String, dynamic> json) => DashboardStats(
customerTotal: toIntOr(json['customerTotal'], 0),
customerMonthlyNew: toIntOr(json['customerMonthlyNew'], 0),
contractTotal: toIntOr(json['contractTotal'], 0),
contractYearAmount: (json['contractYearAmount'] as num?) ?? 0,
surveyPending: toIntOr(json['surveyPending'], 0),
surveyTotal: toIntOr(json['surveyTotal'], 0),
visitMonthly: toIntOr(json['visitMonthly'], 0),
visitTotal: toIntOr(json['visitTotal'], 0),
planTotal: toIntOr(json['planTotal'], 0),
acceptTotal: toIntOr(json['acceptTotal'], 0),
surveyByStatus: _nameValues(json['surveyByStatus']),
modules: _nameValues(json['modules']),
trend: (json['trend'] as List? ?? [])
.map((e) => (e as Map).cast<String, dynamic>())
.toList(),
customerStatus: _nameValues(json['customerStatus']),
customerSignRate: (json['customerSignRate'] as num?) ?? 0,
surveyList: (json['surveyList'] as List? ?? [])
.map((e) => DashboardSurveyItem.fromJson((e as Map).cast<String, dynamic>()))
.toList(),
projects: (json['projects'] as List? ?? [])
.map((e) => DashboardProjectItem.fromJson((e as Map).cast<String, dynamic>()))
.toList(),
);
static List<NameValue> _nameValues(dynamic raw) => (raw as List? ?? [])
.map((e) => NameValue.fromJson((e as Map).cast<String, dynamic>()))
.toList();
}