import Combine import CoreDomain import CoreModel /// Fake 打卡仓库(骨架阶段返回假数据,可提交)。 public final class FakeCheckinRepository: CheckinRepository, @unchecked Sendable { private let record: CurrentValueSubject public init() { record = CurrentValueSubject(Self.seed()) } public func observeCheckin() -> AsyncThrowingStream { Self.stream(record) } public func submitCheckin(status: CheckinStatus) async throws { try await Task.sleep(for: .milliseconds(300)) var current = record.value current = CheckinRecord( classDate: current.classDate, weekday: current.weekday, dayNum: current.dayNum, checked: true, status: status, groupName: current.groupName, groupMembers: current.groupMembers.map { member in guard member.id == "me" else { return member } return GroupMember(id: member.id, name: member.name, checkedIn: true, checkinTime: "现在", status: status) }, personalHistory: current.personalHistory ) record.value = current } private static func stream(_ subject: CurrentValueSubject) -> AsyncThrowingStream { AsyncThrowingStream { continuation in let cancellable = subject.sink { continuation.yield($0) } continuation.onTermination = { _ in cancellable.cancel() } } } private static func seed() -> CheckinRecord { CheckinRecord( classDate: "2026-09-09", weekday: "周三", dayNum: 9, checked: false, status: nil, groupName: "进阶一组", groupMembers: [ GroupMember(id: "m1", name: "张三", checkedIn: true, checkinTime: "19:02", status: .normal), GroupMember(id: "m2", name: "李四", checkedIn: true, checkinTime: "19:30", status: .late), GroupMember(id: "me", name: "我", checkedIn: false, checkinTime: nil, status: nil), GroupMember(id: "m3", name: "王五", checkedIn: true, checkinTime: "09:10", status: .leave), GroupMember(id: "m4", name: "赵六", checkedIn: false, checkinTime: nil, status: nil), ], personalHistory: [ PersonalCheckinRecord(date: "2026-09-06", status: .normal, time: "19:05"), PersonalCheckinRecord(date: "2026-09-02", status: .late, time: "19:32"), ] ) } }