feat: 新增勘察派单功能及拜访详情页操作

新增客户空间拓扑API、勘察明细模型,重构勘察接口,新增拜访详情页操作逻辑及新建勘察派单页面
This commit is contained in:
andyesfly committed 2026-10-17 10:10:02 +08:00
1 parent 7ad604ff8b
commit 83df770eaa
10 files changed
+2788 -529

No files matched your search

@@ -74,4 +74,12 @@ class CustomerApi {
.map((e) => CustomerOption.fromJson((e as Map).cast<String, dynamic>()))
.toList(),
);
/// 客户空间拓扑:一次返回 建筑 → 楼层 → 房间(勘察明细取建筑/楼层/房间用)。
Future<ApiResponse<CustomerTopology>> topology(int customerId) =>
_client.get<CustomerTopology>(
'/customer-circuits/topology',
query: {'customerId': customerId},
parse: (d) => CustomerTopology.fromJson((d as Map).cast<String, dynamic>()),
);
}
@@ -140,4 +140,86 @@ Color customerStatusBarColor(int status) => switch (status) {
3 => AppColors.tertiaryContainer,
4 => AppColors.statusError,
_ => AppColors.borderRule,
};
};
/// 客户空间拓扑(`/api/customer-circuits/topology`):建筑 → 楼层 → 房间。
class CustomerTopology {
const CustomerTopology({required this.buildings});
final List<CustomerTopologyBuilding> buildings;
factory CustomerTopology.fromJson(Map<String, dynamic> json) => CustomerTopology(
buildings: (json['buildings'] as List? ?? [])
.map((e) => CustomerTopologyBuilding.fromJson((e as Map).cast<String, dynamic>()))
.toList(),
);
}
class CustomerTopologyBuilding {
const CustomerTopologyBuilding({
required this.id,
required this.buildingName,
required this.floorCount,
required this.floorDownCount,
required this.floors,
});
final int id;
final String buildingName;
/// 地上楼层数(地上 1..N)。
final int floorCount;
/// 地下楼层数(地下 负1..负M)。
final int floorDownCount;
final List<CustomerTopologyFloor> floors;
factory CustomerTopologyBuilding.fromJson(Map<String, dynamic> json) =>
CustomerTopologyBuilding(
id: toIntOr(json['id'], 0),
buildingName: json['buildingName'] as String? ?? '',
floorCount: toIntOr(json['floorCount'], 0),
floorDownCount: toIntOr(json['floorDownCount'], 0),
floors: (json['floors'] as List? ?? [])
.map((e) => CustomerTopologyFloor.fromJson((e as Map).cast<String, dynamic>()))
.toList(),
);
}
class CustomerTopologyFloor {
const CustomerTopologyFloor({required this.floorNo, required this.rooms});
/// 楼层:正数为地上、负数为地下,如 `"1"` / `"-1"`。
final String floorNo;
final List<CustomerTopologyRoom> rooms;
factory CustomerTopologyFloor.fromJson(Map<String, dynamic> json) =>
CustomerTopologyFloor(
floorNo: json['floorNo'] == null ? '' : json['floorNo'].toString(),
rooms: (json['rooms'] as List? ?? [])
.map((e) => CustomerTopologyRoom.fromJson((e as Map).cast<String, dynamic>()))
.toList(),
);
}
class CustomerTopologyRoom {
const CustomerTopologyRoom({
required this.id,
required this.roomName,
required this.buildingId,
required this.floorNo,
});
final int id;
final String roomName;
final int buildingId;
final String floorNo;
factory CustomerTopologyRoom.fromJson(Map<String, dynamic> json) =>
CustomerTopologyRoom(
id: toIntOr(json['id'], 0),
roomName: json['roomName'] as String? ?? '',
buildingId: toIntOr(json['buildingId'], 0),
floorNo: json['floorNo'] == null ? '' : json['floorNo'].toString(),
);
}