Files
e-party-iOS/yana/ContentView.swift
edwinQQQ 007c10daaf feat: 添加Swift Package管理和API功能模块
新增Package.swift和Package.resolved文件以支持Swift Package管理,创建API相关文件(API.swift、APICaller.swift、APIConstants.swift、APIEndpoints.swift、APIService.swift、APILogger.swift、APIModels.swift、Integration-Guide.md)以实现API请求管理和网络交互功能,增强项目的功能性和可扩展性。同时更新.gitignore以排除构建文件和临时文件。
2025-06-04 17:25:21 +08:00

226 lines
9.7 KiB
Swift

//
// ContentView.swift
// yana
//
// Created by P on 2025/4/21.
//
import SwiftUI
import ComposableArchitecture
// MARK: - API Response Models
struct InitResponse: Codable, Equatable {
let status: String
let message: String?
let data: InitData?
}
struct InitData: Codable, Equatable {
let version: String?
let timestamp: Int?
let config: [String: String]?
}
// MARK: - Local UI Log Level Enum
enum UILogLevel: String, CaseIterable {
case none = "无日志"
case basic = "基础日志"
case detailed = "详细日志"
}
struct ContentView: View {
let store: StoreOf<LoginFeature>
let initStore: StoreOf<InitFeature>
let configStore: StoreOf<ConfigFeature>
@State private var selectedLogLevel: APILogger.LogLevel = APILogger.logLevel
@State private var selectedTab = 0
var body: some View {
TabView(selection: $selectedTab) {
//
VStack {
//
VStack(alignment: .leading, spacing: 8) {
Text("日志级别:")
.font(.headline)
.foregroundColor(.primary)
Picker("日志级别", selection: $selectedLogLevel) {
Text("无日志").tag(APILogger.LogLevel.none)
Text("基础日志").tag(APILogger.LogLevel.basic)
Text("详细日志").tag(APILogger.LogLevel.detailed)
}
.pickerStyle(SegmentedPickerStyle())
}
.padding()
.background(Color.gray.opacity(0.1))
.cornerRadius(10)
Spacer()
VStack(spacing: 20) {
Text("yana")
.font(.largeTitle)
.fontWeight(.bold)
VStack(spacing: 15) {
WithViewStore(store, observe: { $0 }) { viewStore in
TextField("账号", text: viewStore.binding(
get: \.account,
send: { LoginFeature.Action.updateAccount($0) }
))
.textFieldStyle(RoundedBorderTextFieldStyle())
.autocorrectionDisabled(true)
SecureField("密码", text: viewStore.binding(
get: \.password,
send: { LoginFeature.Action.updatePassword($0) }
))
.textFieldStyle(RoundedBorderTextFieldStyle())
}
}
.padding(.horizontal)
WithViewStore(store, observe: { $0 }) { viewStore in
if let error = viewStore.error {
Text(error)
.foregroundColor(.red)
.font(.caption)
.multilineTextAlignment(.center)
.padding(.horizontal)
}
VStack(spacing: 10) {
Button(action: {
viewStore.send(.login)
}) {
HStack {
if viewStore.isLoading {
ProgressView()
.scaleEffect(0.8)
.progressViewStyle(CircularProgressViewStyle(tint: .white))
}
Text(viewStore.isLoading ? "登录中..." : "登录")
}
.frame(maxWidth: .infinity)
.padding()
.background(viewStore.isLoading ? Color.gray : Color.blue)
.foregroundColor(.white)
.cornerRadius(10)
}
.disabled(viewStore.isLoading || viewStore.account.isEmpty || viewStore.password.isEmpty)
WithViewStore(initStore, observe: { $0 }) { initViewStore in
Button(action: {
initViewStore.send(.initialize)
}) {
HStack {
if initViewStore.isLoading {
ProgressView()
.scaleEffect(0.8)
.progressViewStyle(CircularProgressViewStyle(tint: .white))
}
Text(initViewStore.isLoading ? "测试中..." : "测试初始化")
}
.frame(maxWidth: .infinity)
.padding()
.background(initViewStore.isLoading ? Color.gray : Color.green)
.foregroundColor(.white)
.cornerRadius(10)
}
.disabled(initViewStore.isLoading)
// API
if let response = initViewStore.response {
VStack(alignment: .leading, spacing: 8) {
HStack {
Text("API 测试结果:")
.font(.headline)
.foregroundColor(.primary)
}
ScrollView {
VStack(alignment: .leading, spacing: 4) {
Text("状态: \(response.status)")
if let message = response.message {
Text("消息: \(message)")
}
if let data = response.data {
Text("版本: \(data.version ?? "未知")")
Text("时间戳: \(data.timestamp ?? 0)")
if let config = data.config {
Text("配置:")
ForEach(Array(config.keys), id: \.self) { key in
Text(" \(key): \(config[key] ?? "")")
}
}
}
}
.font(.system(.caption, design: .monospaced))
.foregroundColor(.secondary)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(8)
.background(Color.gray.opacity(0.1))
.cornerRadius(8)
}
.frame(maxHeight: 200)
}
.padding()
.background(Color.gray.opacity(0.05))
.cornerRadius(10)
}
if let error = initViewStore.error {
Text(error)
.foregroundColor(.red)
.font(.caption)
.multilineTextAlignment(.center)
.padding()
}
}
.padding(.horizontal)
}
}
}
Spacer()
}
.padding()
.tabItem {
Label("登录", systemImage: "person.circle")
}
.tag(0)
// API
ConfigView(store: configStore)
.tabItem {
Label("API 测试", systemImage: "network")
}
.tag(1)
}
.onChange(of: selectedLogLevel) { newValue in
APILogger.logLevel = newValue
}
}
}
#Preview {
ContentView(
store: Store(
initialState: LoginFeature.State()
) {
LoginFeature()
},
initStore: Store(
initialState: InitFeature.State()
) {
InitFeature()
},
configStore: Store(
initialState: ConfigFeature.State()
) {
ConfigFeature()
}
)
}