Files
ios-client/IosClientKit/Sources/CoreRepository/FakePlanRepository.swift

137 lines
5.1 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import Combine
import CoreDomain
import CoreModel
import Foundation
/// Fake 计划仓库(骨架阶段返回假数据,可提交)。
public final class FakePlanRepository: PlanRepository, @unchecked Sendable {
private let plans: [PlanType: CurrentValueSubject<PlanRecord, Never>]
private var submits: [String: CurrentValueSubject<PlanSubmitData, Never>] = [:]
private let lock = NSLock()
public init() {
var dict: [PlanType: CurrentValueSubject<PlanRecord, Never>] = [:]
for type in PlanType.allCases {
dict[type] = CurrentValueSubject<PlanRecord, Never>(Self.seedPlan(type))
}
plans = dict
}
public func observePlan(type: PlanType) -> AsyncThrowingStream<PlanRecord, Error> {
Self.stream(plans[type]!)
}
public func observePlanSubmit(type: PlanType, periodKey: String) -> AsyncThrowingStream<PlanSubmitData, Error> {
Self.stream(submitSubject(type: type, periodKey: periodKey))
}
public func savePlan(type: PlanType, periodKey: String, content: String, attachments: [String]) async throws {
try await Task.sleep(for: .milliseconds(300))
let submit = submitSubject(type: type, periodKey: periodKey)
let currentSubmit = submit.value
submit.value = PlanSubmitData(
content: content,
attachments: attachments,
checked: true,
canSubmit: currentSubmit.canSubmit,
message: currentSubmit.message,
history: currentSubmit.history
)
let plan = plans[type]!
let currentPlan = plan.value
plan.value = PlanRecord(
type: currentPlan.type,
periodKey: currentPlan.periodKey,
canSubmit: currentPlan.canSubmit,
message: currentPlan.message,
myChecked: true,
myRecord: MyPlanRecord(status: "已完成", submittedTime: "现在", content: content, attachments: attachments),
groups: currentPlan.groups,
unassignedCount: currentPlan.unassignedCount
)
}
private func submitSubject(type: PlanType, periodKey: String) -> CurrentValueSubject<PlanSubmitData, Never> {
let key = "\(type.rawValue):\(periodKey)"
lock.lock()
defer { lock.unlock() }
if let existing = submits[key] {
return existing
}
let subject = CurrentValueSubject<PlanSubmitData, Never>(Self.seedSubmit(type: type))
submits[key] = subject
return subject
}
private static func stream<T>(_ subject: CurrentValueSubject<T, Never>) -> AsyncThrowingStream<T, Error> {
AsyncThrowingStream { continuation in
let cancellable = subject.sink { continuation.yield($0) }
continuation.onTermination = { _ in cancellable.cancel() }
}
}
private static func seedPlan(_ type: PlanType) -> PlanRecord {
PlanRecord(
type: type,
periodKey: periodKey(for: type),
canSubmit: true,
message: type == .weekly ? "本周计划提交截止:周日晚 23:59" : nil,
myChecked: type == .weekly,
myRecord: type == .weekly
? MyPlanRecord(status: "已完成", submittedTime: "今天 18:30", content: "本周完成两章学习,整理笔记并复习错题。", attachments: ["图1", "图2"])
: nil,
groups: seedGroups(),
unassignedCount: 2
)
}
private static func seedSubmit(type: PlanType) -> PlanSubmitData {
if type == .weekly {
return PlanSubmitData(
content: "本周完成两章学习,整理笔记并复习错题。",
attachments: ["图1", "图2"],
checked: true,
canSubmit: true,
message: nil,
history: []
)
}
return PlanSubmitData(
content: "",
attachments: [],
checked: false,
canSubmit: true,
message: nil,
history: [
MyPlanRecord(status: "已完成", submittedTime: "2026-08 完成", content: "上月计划内容……", attachments: []),
]
)
}
private static func periodKey(for type: PlanType) -> String {
switch type {
case .weekly: return "2026 第 37 周"
case .monthly: return "2026 年 9 月"
case .yearly: return "2026 年"
}
}
private static func seedGroups() -> [PlanGroup] {
[
PlanGroup(id: "g1", name: "进阶一组", checkedCount: 4, memberCount: 6, members: seedMembers()),
PlanGroup(id: "g2", name: "进阶二组", checkedCount: 5, memberCount: 5, members: seedMembers()),
PlanGroup(id: "g3", name: "进阶三组", checkedCount: 2, memberCount: 7, members: seedMembers()),
]
}
private static func seedMembers() -> [PlanMember] {
[
PlanMember(id: "p1", name: "张三", filled: true),
PlanMember(id: "p2", name: "李四", filled: true),
PlanMember(id: "p3", name: "王五", filled: false),
]
}
}