模块化 AppStore 并完善素材管理与个人空间设置。

将会话、权限、位置、收款与排队存储拆分为独立模块,同步更新各 ViewModel 与单元测试,并补充素材管理 UI 与个人空间设置交互。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-13 11:01:08 +08:00
parent ceca780ab3
commit 005349f8e6
128 changed files with 2953 additions and 1123 deletions

View File

@ -118,9 +118,9 @@ final class ScenicQueueFeatureTests: XCTestCase {
let defaults = UserDefaults(suiteName: "ScenicQueueFeatureTests.settings")!
defaults.removePersistentDomain(forName: "ScenicQueueFeatureTests.settings")
let store = AppStore(defaults: defaults)
store.userId = "u1"
store.accountType = "photog"
store.currentScenicId = 11
store.session.userId = "u1"
store.session.accountType = .unknown("photog")
store.session.currentScenicId = 11
let api = MockScenicQueueAPI()
let tts = MockScenicQueueTTSManager()
let viewModel = ScenicQueueSettingsViewModel(appStore: store, ttsManager: tts)
@ -165,20 +165,20 @@ final class ScenicQueueFeatureTests: XCTestCase {
XCTAssertEqual(request?.missCallRequeueOffset, 2)
XCTAssertEqual(request?.autoCallNextCount, 3)
XCTAssertEqual(request?.voiceBroadcasts.map(\.content), ["请准备拍摄", "第二条"])
XCTAssertEqual(store.scenicQueuePunchSpotName, "东门打卡点")
XCTAssertEqual(store.scenicQueueSettingsSnapshot()?.shootMinute, 9)
XCTAssertEqual(store.scenicQueue.punchSpotName, "东门打卡点")
XCTAssertEqual(store.scenicQueue.settingsSnapshot()?.shootMinute, 9)
}
func testMainViewModelGatePagingActionsTTSAndSocketFiltering() async {
let defaults = UserDefaults(suiteName: "ScenicQueueFeatureTests.main")!
defaults.removePersistentDomain(forName: "ScenicQueueFeatureTests.main")
let store = AppStore(defaults: defaults)
store.userId = "9"
store.accountType = "photog"
store.currentScenicId = 11
store.scenicQueuePunchSpotId = "22"
store.scenicQueuePunchSpotName = "东门打卡点"
store.saveScenicQueueSettingsSnapshot(
store.session.userId = "9"
store.session.accountType = .unknown("photog")
store.session.currentScenicId = 11
store.scenicQueue.punchSpotId = "22"
store.scenicQueue.punchSpotName = "东门打卡点"
store.scenicQueue.saveSettingsSnapshot(
ScenicQueueSettingsSnapshot(showStartShootingButton: true, quickCallButtonEnabled: true, prepareCallButtonEnabled: true)
)
let api = MockScenicQueueAPI()
@ -248,28 +248,28 @@ final class ScenicQueueFeatureTests: XCTestCase {
defaults.removePersistentDomain(forName: "ScenicQueueFeatureTests.store")
let store = AppStore(defaults: defaults)
store.userId = "1"
store.accountType = "photog"
store.scenicQueuePunchSpotId = "22"
store.scenicQueuePunchSpotName = "东门打卡点"
store.scenicQueueRemark = "播报"
store.saveScenicQueueSettingsSnapshot(ScenicQueueSettingsSnapshot(shootMinute: 3))
store.saveScenicQueuePresetVoices(["a", "b", "c", "d", "e", "f"])
store.session.userId = "1"
store.session.accountType = .unknown("photog")
store.scenicQueue.punchSpotId = "22"
store.scenicQueue.punchSpotName = "东门打卡点"
store.scenicQueue.remark = "播报"
store.scenicQueue.saveSettingsSnapshot(ScenicQueueSettingsSnapshot(shootMinute: 3))
store.scenicQueue.savePresetVoices(["a", "b", "c", "d", "e", "f"])
store.userId = "2"
store.accountType = "photog"
XCTAssertEqual(store.scenicQueuePunchSpotId, "")
XCTAssertNil(store.scenicQueueSettingsSnapshot())
store.session.userId = "2"
store.session.accountType = .unknown("photog")
XCTAssertEqual(store.scenicQueue.punchSpotId, "")
XCTAssertNil(store.scenicQueue.settingsSnapshot())
store.userId = "1"
store.accountType = "photog"
XCTAssertEqual(store.scenicQueuePunchSpotId, "22")
XCTAssertEqual(store.scenicQueuePresetVoices(), ["a", "b", "c", "d", "e"])
store.session.userId = "1"
store.session.accountType = .unknown("photog")
XCTAssertEqual(store.scenicQueue.punchSpotId, "22")
XCTAssertEqual(store.scenicQueue.presetVoices(), ["a", "b", "c", "d", "e"])
store.logout()
store.userId = "1"
store.accountType = "photog"
XCTAssertEqual(store.scenicQueuePunchSpotId, "")
XCTAssertNil(store.scenicQueueSettingsSnapshot())
store.session.userId = "1"
store.session.accountType = .unknown("photog")
XCTAssertEqual(store.scenicQueue.punchSpotId, "")
XCTAssertNil(store.scenicQueue.settingsSnapshot())
}
func testAliyunNLSTokenProviderBuildsSignedCreateTokenRequest() async throws {
@ -321,8 +321,8 @@ final class ScenicQueueFeatureTests: XCTestCase {
let defaults = UserDefaults(suiteName: "ScenicQueueFeatureTests.offlineTTS")!
defaults.removePersistentDomain(forName: "ScenicQueueFeatureTests.offlineTTS")
let store = AppStore(defaults: defaults)
store.userId = "u1"
store.accountType = "photog"
store.session.userId = "u1"
store.session.accountType = .unknown("photog")
let tts = MockScenicQueueTTSManager()
let viewModel = ScenicQueueSettingsViewModel(appStore: store, ttsManager: tts)
var messages: [String] = []
@ -330,7 +330,7 @@ final class ScenicQueueFeatureTests: XCTestCase {
viewModel.setUseOfflineTTS(true)
XCTAssertFalse(store.scenicQueueUseOfflineTTS)
XCTAssertFalse(store.scenicQueue.useOfflineTTS)
XCTAssertEqual(messages.last, "离线语音资源未安装")
}
}