생성 때 고른 행성 형태·색 표시 · HOME 주간 정보
This commit is contained in:
@@ -184,6 +184,17 @@ class FirestoreHomeRepository implements HomeRepository {
|
||||
.limit(20)
|
||||
.get();
|
||||
|
||||
// HOME 주간 정보(A-37) — 주간 공식 Snapshot 최신 · 직전 두 개(순위 · 변동 · 성장 기준선).
|
||||
final snapshotsF = fandomId.isEmpty
|
||||
? null
|
||||
: db
|
||||
.collection('rankingSnapshots')
|
||||
.orderBy('createdAt', descending: true)
|
||||
.limit(2)
|
||||
.get()
|
||||
.then((q) => [for (final d in q.docs) d.data()])
|
||||
.catchError((Object _) => <Map<String, dynamic>>[]);
|
||||
|
||||
final wallet = (await walletF).data() ?? const <String, dynamic>{};
|
||||
final fandom = fandomF == null
|
||||
? const <String, dynamic>{}
|
||||
@@ -226,7 +237,23 @@ class FirestoreHomeRepository implements HomeRepository {
|
||||
|
||||
final progressById = {for (final doc in progress) doc.id: doc.data()};
|
||||
|
||||
HomeWeekly? weekly;
|
||||
if (snapshotsF != null) {
|
||||
final snapshots = await snapshotsF;
|
||||
final since = snapshots.firstOrNull?['createdAt'] is Timestamp
|
||||
? (snapshots.first['createdAt'] as Timestamp).toDate()
|
||||
: kstWeekStart(DateTime.now());
|
||||
weekly = HomeWeekly.from(
|
||||
fandomId: fandomId,
|
||||
snapshots: snapshots,
|
||||
fandom: fandom,
|
||||
myWeekPop: await _myWeekGrowth(uid, fandomId, since),
|
||||
wallet: wallet,
|
||||
);
|
||||
}
|
||||
|
||||
return HomeSnapshot(
|
||||
weekly: weekly,
|
||||
popBalance: wallet.intOr('activityBalance'),
|
||||
fandomId: fandomId,
|
||||
liveTicker: fandom.strOr('liveTicker').isEmpty
|
||||
@@ -300,6 +327,27 @@ class FirestoreHomeRepository implements HomeRepository {
|
||||
);
|
||||
}
|
||||
|
||||
/// 이번 주 내가 [fandomId] 행성 성장에 보탠 Growth POP — 원장과 같은 트랜잭션에서 쓰는
|
||||
/// `users/{uid}/growthEvents`(역분개는 음수 행)의 [since] 이후 합. 읽지 못하면 null.
|
||||
// ponytail: 한 주치 성장 행을 전부 읽어 합한다. 한 사용자가 주에 수천 건을 넘기면 서버 집계 필드로 옮긴다.
|
||||
Future<num?> _myWeekGrowth(String uid, String fandomId, DateTime since) async {
|
||||
try {
|
||||
final q = await _backend.db
|
||||
.collection('users/$uid/growthEvents')
|
||||
.where('createdAt', isGreaterThanOrEqualTo: Timestamp.fromDate(since))
|
||||
.get();
|
||||
num sum = 0;
|
||||
for (final d in q.docs) {
|
||||
final data = d.data();
|
||||
final amount = data['amount'];
|
||||
if (data['fandomIdAtPayout'] == fandomId && amount is num) sum += amount;
|
||||
}
|
||||
return sum;
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<PlanetGrowth> _growth(
|
||||
Map<String, dynamic> fandom,
|
||||
String fandomId,
|
||||
@@ -529,6 +577,13 @@ String kstDayKey([DateTime? at]) => (at ?? DateTime.now().toUtc())
|
||||
.toIso8601String()
|
||||
.substring(0, 10);
|
||||
|
||||
/// 이번 주 시작 — KST 월요일 00:00(서버 `weekKeyOf` 와 같은 주 경계). 주간 Snapshot 이 아직 없을 때만 쓴다.
|
||||
DateTime kstWeekStart(DateTime at) {
|
||||
final kst = at.toUtc().add(const Duration(hours: 9));
|
||||
final monday = DateTime.utc(kst.year, kst.month, kst.day - (kst.weekday - 1));
|
||||
return monday.subtract(const Duration(hours: 9));
|
||||
}
|
||||
|
||||
/// HOME TODAY'S QUEST 의 관리자 퀘스트 — `authorUid` 가 없는 것만, `createdAt` 최신순
|
||||
/// (설명 프레임 `2097:16397` 「관리자 퀘스트 - 최신순으로 최대 3개 노출」).
|
||||
List<T> adminQuestsLatest<T>(
|
||||
|
||||
Reference in New Issue
Block a user