feat: 定义仓库协议与用例(含会话)
This commit is contained in:
9
IosClientKit/Sources/CoreDomain/CheckinRepository.swift
Normal file
9
IosClientKit/Sources/CoreDomain/CheckinRepository.swift
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import CoreModel
|
||||||
|
|
||||||
|
/// 打卡数据仓库协议(定义在 domain 层,实现放 CoreRepository)。
|
||||||
|
public protocol CheckinRepository: Sendable {
|
||||||
|
/// 观察打卡数据。
|
||||||
|
func observeCheckin() -> AsyncThrowingStream<CheckinRecord, Error>
|
||||||
|
/// 提交打卡状态。
|
||||||
|
func submitCheckin(status: CheckinStatus) async throws
|
||||||
|
}
|
||||||
18
IosClientKit/Sources/CoreDomain/CheckinUseCase.swift
Normal file
18
IosClientKit/Sources/CoreDomain/CheckinUseCase.swift
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import CoreModel
|
||||||
|
|
||||||
|
/// 获取/提交打卡数据的用例。
|
||||||
|
public struct CheckinUseCase: Sendable {
|
||||||
|
private let repository: CheckinRepository
|
||||||
|
|
||||||
|
public init(repository: CheckinRepository) {
|
||||||
|
self.repository = repository
|
||||||
|
}
|
||||||
|
|
||||||
|
public func observeCheckin() -> AsyncThrowingStream<CheckinRecord, Error> {
|
||||||
|
repository.observeCheckin()
|
||||||
|
}
|
||||||
|
|
||||||
|
public func submitCheckin(status: CheckinStatus) async throws {
|
||||||
|
try await repository.submitCheckin(status: status)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
import CoreModel
|
import CoreModel
|
||||||
|
|
||||||
/// Home 数据仓库协议(定义在 domain 层,实现放 CoreRepository)。
|
/// Home 数据仓库协议(定义在 domain 层,实现放 CoreRepository)。
|
||||||
/// Kotlin: interface HomeRepository { fun observeHome(): Flow<HomeData> }
|
|
||||||
public protocol HomeRepository: Sendable {
|
public protocol HomeRepository: Sendable {
|
||||||
/// Kotlin: Flow<HomeData> → Swift: AsyncThrowingStream<HomeData, Error>
|
/// 已登录首页。
|
||||||
func observeHome() -> AsyncThrowingStream<HomeData, Error>
|
func observeHome() -> AsyncThrowingStream<HomeData, Error>
|
||||||
|
/// 游客首页。
|
||||||
|
func observeGuestHome() -> AsyncThrowingStream<HomeData, Error>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import CoreModel
|
import CoreModel
|
||||||
|
|
||||||
/// 获取 Home 数据的用例。
|
/// 获取 Home 数据的用例。
|
||||||
/// Kotlin: class HomeUseCase(...) { suspend operator fun invoke(): HomeData }
|
|
||||||
public struct HomeUseCase: Sendable {
|
public struct HomeUseCase: Sendable {
|
||||||
private let repository: HomeRepository
|
private let repository: HomeRepository
|
||||||
|
|
||||||
@@ -9,8 +8,13 @@ public struct HomeUseCase: Sendable {
|
|||||||
self.repository = repository
|
self.repository = repository
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Kotlin: Flow<HomeData> → Swift: AsyncThrowingStream<HomeData, Error>
|
/// 已登录首页。
|
||||||
public func observeHome() -> AsyncThrowingStream<HomeData, Error> {
|
public func observeHome() -> AsyncThrowingStream<HomeData, Error> {
|
||||||
repository.observeHome()
|
repository.observeHome()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 游客首页。
|
||||||
|
public func observeGuestHome() -> AsyncThrowingStream<HomeData, Error> {
|
||||||
|
repository.observeGuestHome()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
8
IosClientKit/Sources/CoreDomain/PlanRepository.swift
Normal file
8
IosClientKit/Sources/CoreDomain/PlanRepository.swift
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import CoreModel
|
||||||
|
|
||||||
|
/// 计划数据仓库协议(定义在 domain 层,实现放 CoreRepository)。
|
||||||
|
public protocol PlanRepository: Sendable {
|
||||||
|
func observePlan(type: PlanType) -> AsyncThrowingStream<PlanRecord, Error>
|
||||||
|
func observePlanSubmit(type: PlanType, periodKey: String) -> AsyncThrowingStream<PlanSubmitData, Error>
|
||||||
|
func savePlan(type: PlanType, periodKey: String, content: String, attachments: [String]) async throws
|
||||||
|
}
|
||||||
22
IosClientKit/Sources/CoreDomain/PlanUseCase.swift
Normal file
22
IosClientKit/Sources/CoreDomain/PlanUseCase.swift
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import CoreModel
|
||||||
|
|
||||||
|
/// 获取/提交计划数据的用例。
|
||||||
|
public struct PlanUseCase: Sendable {
|
||||||
|
private let repository: PlanRepository
|
||||||
|
|
||||||
|
public init(repository: PlanRepository) {
|
||||||
|
self.repository = repository
|
||||||
|
}
|
||||||
|
|
||||||
|
public func observePlan(type: PlanType) -> AsyncThrowingStream<PlanRecord, Error> {
|
||||||
|
repository.observePlan(type: type)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func observePlanSubmit(type: PlanType, periodKey: String) -> AsyncThrowingStream<PlanSubmitData, Error> {
|
||||||
|
repository.observePlanSubmit(type: type, periodKey: periodKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func savePlan(type: PlanType, periodKey: String, content: String, attachments: [String]) async throws {
|
||||||
|
try await repository.savePlan(type: type, periodKey: periodKey, content: content, attachments: attachments)
|
||||||
|
}
|
||||||
|
}
|
||||||
7
IosClientKit/Sources/CoreDomain/ProfileRepository.swift
Normal file
7
IosClientKit/Sources/CoreDomain/ProfileRepository.swift
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import CoreModel
|
||||||
|
|
||||||
|
/// 个人资料仓库协议(定义在 domain 层,实现放 CoreRepository)。
|
||||||
|
public protocol ProfileRepository: Sendable {
|
||||||
|
/// Kotlin: Flow<UserProfile> → Swift: AsyncThrowingStream<UserProfile, Error>
|
||||||
|
func observeProfile() -> AsyncThrowingStream<UserProfile, Error>
|
||||||
|
}
|
||||||
14
IosClientKit/Sources/CoreDomain/ProfileUseCase.swift
Normal file
14
IosClientKit/Sources/CoreDomain/ProfileUseCase.swift
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import CoreModel
|
||||||
|
|
||||||
|
/// 获取个人资料的用例。
|
||||||
|
public struct ProfileUseCase: Sendable {
|
||||||
|
private let repository: ProfileRepository
|
||||||
|
|
||||||
|
public init(repository: ProfileRepository) {
|
||||||
|
self.repository = repository
|
||||||
|
}
|
||||||
|
|
||||||
|
public func observeProfile() -> AsyncThrowingStream<UserProfile, Error> {
|
||||||
|
repository.observeProfile()
|
||||||
|
}
|
||||||
|
}
|
||||||
28
IosClientKit/Sources/CoreDomain/SessionRepository.swift
Normal file
28
IosClientKit/Sources/CoreDomain/SessionRepository.swift
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import Foundation
|
||||||
|
|
||||||
|
/// 会话相关错误。
|
||||||
|
public enum SessionError: Error, Sendable, LocalizedError {
|
||||||
|
case invalidPhone
|
||||||
|
case wrongCode
|
||||||
|
case phoneNotMatched
|
||||||
|
|
||||||
|
public var errorDescription: String? {
|
||||||
|
switch self {
|
||||||
|
case .invalidPhone: return "请输入正确的手机号"
|
||||||
|
case .wrongCode: return "验证码错误"
|
||||||
|
case .phoneNotMatched: return "手机号未匹配,无法登录"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 会话仓库协议(登录态 / 手机号登录)。
|
||||||
|
public protocol SessionRepository: Sendable {
|
||||||
|
/// 观察登录态。
|
||||||
|
func observeIsLoggedIn() -> AsyncThrowingStream<Bool, Error>
|
||||||
|
/// 请求短信验证码。
|
||||||
|
func requestSmsCode(phone: String) async throws
|
||||||
|
/// 手机号 + 验证码登录。
|
||||||
|
func login(phone: String, code: String) async throws
|
||||||
|
/// 退出登录。
|
||||||
|
func logout() async throws
|
||||||
|
}
|
||||||
24
IosClientKit/Sources/CoreDomain/SessionUseCase.swift
Normal file
24
IosClientKit/Sources/CoreDomain/SessionUseCase.swift
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/// 会话用例。
|
||||||
|
public struct SessionUseCase: Sendable {
|
||||||
|
private let repository: SessionRepository
|
||||||
|
|
||||||
|
public init(repository: SessionRepository) {
|
||||||
|
self.repository = repository
|
||||||
|
}
|
||||||
|
|
||||||
|
public func observeIsLoggedIn() -> AsyncThrowingStream<Bool, Error> {
|
||||||
|
repository.observeIsLoggedIn()
|
||||||
|
}
|
||||||
|
|
||||||
|
public func requestSmsCode(phone: String) async throws {
|
||||||
|
try await repository.requestSmsCode(phone: phone)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func login(phone: String, code: String) async throws {
|
||||||
|
try await repository.login(phone: phone, code: code)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func logout() async throws {
|
||||||
|
try await repository.logout()
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user