didvan-app/lib/models/home_page_content/swot.dart

109 lines
3.7 KiB
Dart

import 'package:didvan/models/content/content_item.dart';
class SwotItem {
final int id;
final String title;
final String description;
final String category;
final String type;
final String imageUrl;
final double x1;
final double y1;
final String createdAt;
/// uuid اصلی content-service (در محتوای جدید). در داده‌ی قدیمی null است.
final String? keycloakId;
SwotItem({
required this.id,
required this.title,
required this.description,
required this.category,
required this.type,
required this.imageUrl,
required this.x1,
required this.y1,
required this.createdAt,
this.keycloakId,
});
factory SwotItem.fromJson(Map<String, dynamic> json) {
return SwotItem(
id: json['id'],
title: json['title'],
description: json['description'],
category: json['category'],
type: json['type'],
imageUrl: json["url"],
x1: json["scoreX1"],
y1: json["scoreY1"],
createdAt: json["createdAt"]
);
}
/// ساختن SwotItem از ContentItem (دسته‌ی «فرصت و تهدید» در content-service).
/// نوع (opportunity/threat) از `metadata.type` می‌آید.
/// عدد (x1, y1) از جدولِ امتیازات در body محاسبه می‌شود:
/// - میانگین ستونِ «۷ سال» برای سطرهای محور X → x1
/// - میانگین ستونِ «۷ سال» برای سطرهای محور Y → y1
factory SwotItem.fromContentItem(ContentItem item) {
// widget قدیمی با type == "THREAT" (uppercase) چک می‌کند.
final isThreat = (item.metaType ?? '').toLowerCase() == 'threat';
final type = isThreat ? 'THREAT' : 'OPPORTUNITY';
final (x1, y1) = _extractScores(item.body);
return SwotItem(
id: item.id.hashCode,
keycloakId: item.id,
title: item.title,
description: item.summary ?? '',
category: item.category?.name ?? 'فرصت و تهدید',
type: type,
imageUrl: item.coverImage ?? '',
x1: x1,
y1: y1,
createdAt: item.publishedAt?.toIso8601String() ?? '',
);
}
/// در body یک بلوک table پیدا می‌کند و میانگینِ ستونِ آخر را برای محورهای
/// X و Y برمی‌گرداند. اگر چیزی پیدا نشد، 0 برمی‌گرداند.
static (double, double) _extractScores(dynamic body) {
try {
if (body is! Map) return (0.0, 0.0);
final blocks = body['blocks'];
if (blocks is! List) return (0.0, 0.0);
for (final block in blocks) {
if (block is! Map) continue;
if (block['type'] != 'table') continue;
final data = block['data'];
if (data is! Map) continue;
final content = data['content'];
if (content is! List || content.isEmpty) continue;
// ستونِ آخر = آخرین مقدار در آرایه‌ی هر سطر.
double xSum = 0, ySum = 0;
int xCount = 0, yCount = 0;
for (var i = 1; i < content.length; i++) {
final row = content[i];
if (row is! List || row.length < 3) continue;
final axis = row[1]?.toString().toUpperCase().trim();
final last = row.last?.toString().trim();
final val = double.tryParse(last ?? '');
if (val == null) continue;
if (axis == 'X') {
xSum += val;
xCount++;
} else if (axis == 'Y') {
ySum += val;
yCount++;
}
}
final x1 = xCount > 0 ? xSum / xCount : 0.0;
final y1 = yCount > 0 ? ySum / yCount : 0.0;
return (x1, y1);
}
} catch (_) {}
return (0.0, 0.0);
}
}