角色列表数据请求
This commit is contained in:
parent
2d4c80e084
commit
1f79e82668
|
|
@ -437,6 +437,7 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 121;
|
||||
DEVELOPMENT_TEAM = 6GS5RC7C89;
|
||||
|
|
@ -460,8 +461,9 @@
|
|||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.personal.ChinaTravel;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.person.ChinaTravel;
|
||||
PRODUCT_NAME = Visual_Novel_iOSLevel;
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = CLPRODUCT;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/Visual_Novel_iOS/CL-Bridging-Header.h";
|
||||
|
|
@ -550,6 +552,7 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 121;
|
||||
DEVELOPMENT_TEAM = 6GS5RC7C89;
|
||||
|
|
@ -573,8 +576,9 @@
|
|||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.personal.ChinaTravel;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.person.ChinaTravel;
|
||||
PRODUCT_NAME = Visual_Novel_iOSLevel;
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = CLAPPSTORE;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/Visual_Novel_iOS/CL-Bridging-Header.h";
|
||||
|
|
@ -607,6 +611,7 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 121;
|
||||
DEVELOPMENT_TEAM = 6GS5RC7C89;
|
||||
|
|
@ -630,8 +635,9 @@
|
|||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.personal.ChinaTravel;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.person.ChinaTravel;
|
||||
PRODUCT_NAME = Visual_Novel_iOSLevel;
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/Visual_Novel_iOS/CL-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
|
|
@ -645,6 +651,7 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 121;
|
||||
DEVELOPMENT_TEAM = 6GS5RC7C89;
|
||||
|
|
@ -668,8 +675,9 @@
|
|||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.personal.ChinaTravel;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.person.ChinaTravel;
|
||||
PRODUCT_NAME = Visual_Novel_iOSLevel;
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/Visual_Novel_iOS/CL-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,15 @@
|
|||
<key>NSAllowsArbitraryLoadsInWebContent</key>
|
||||
<true/>
|
||||
<key>NSExceptionDomains</key>
|
||||
<dict/>
|
||||
<dict>
|
||||
<key>54.223.196.180</key>
|
||||
<dict>
|
||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||
<true/>
|
||||
<key>NSIncludesSubdomains</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>UIAppFonts</key>
|
||||
<array>
|
||||
|
|
|
|||
|
|
@ -43,18 +43,18 @@ struct APIConfig {
|
|||
|
||||
static func apiHeaders() -> [String: String]? {
|
||||
var updatHeaders = headers
|
||||
//
|
||||
// let platform = "IOS" // _\(Bundle.appVersion)
|
||||
// updatHeaders?.updateValue(platform, forKey: "platform")
|
||||
|
||||
let platform = "IOS" // _\(Bundle.appVersion)
|
||||
updatHeaders?.updateValue(platform, forKey: "platform")
|
||||
// let tokenNow = UserCore.shared.token
|
||||
// if tokenNow.count > 0 {
|
||||
// updatHeaders?.updateValue(tokenNow, forKey: "AUTH_TK")
|
||||
// }
|
||||
|
||||
let tokenNow = UserCore.shared.token
|
||||
if tokenNow.count > 0 {
|
||||
updatHeaders?.updateValue(tokenNow, forKey: "AUTH_TK")
|
||||
}
|
||||
// updatHeaders?.updateValue("\(versionNum)", forKey: "versionNum")
|
||||
|
||||
updatHeaders?.updateValue("\(versionNum)", forKey: "versionNum")
|
||||
|
||||
updatHeaders?.updateValue(UIDevice.UUID, forKey: "AUTH_DID")
|
||||
// updatHeaders?.updateValue(UIDevice.UUID, forKey: "AUTH_DID")
|
||||
/*
|
||||
if let lan = Languages.preferedLans.first {
|
||||
updatHeaders?.updateValue(lan.rawValue, forKey: "accept-language")
|
||||
|
|
@ -106,4 +106,9 @@ struct APIConfig {
|
|||
static var pigeon: String{
|
||||
return "https://test-pigeon.crushlevel.ai"
|
||||
}
|
||||
|
||||
static var role: String {
|
||||
// 确保 URL 格式正确,包含协议、域名和端口
|
||||
return "http://54.223.196.180:8091"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,11 +128,14 @@ public enum ServiceErrorEnum: String, Codable {
|
|||
// 假设 ResponseData 是一个泛型结构体,用于包装 API 响应
|
||||
struct ResponseData<T: Codable>: Codable {
|
||||
/// OK or ERROR
|
||||
let status: String?
|
||||
let errorCode: ServiceErrorEnum?
|
||||
let errorMsg: String?
|
||||
let content: T?
|
||||
let traceId : String?
|
||||
// let status: String?
|
||||
// let errorCode: ServiceErrorEnum?
|
||||
// let errorMsg: String?
|
||||
// let content: T?
|
||||
// let traceId : String?
|
||||
let code: Int?
|
||||
let message: String?
|
||||
let data: T?
|
||||
}
|
||||
|
||||
class ResponseContentPageData<T: Codable>: Codable{
|
||||
|
|
@ -213,58 +216,58 @@ extension MoyaProvider {
|
|||
dlog("👉⭐️\(target.path)⭐️ response:\n\(jsonString)")
|
||||
}
|
||||
|
||||
let status = data.status
|
||||
let code = data.errorCode
|
||||
let msg = data.errorMsg
|
||||
// let status = data.status
|
||||
// let code = data.errorCode
|
||||
// let msg = data.errorMsg
|
||||
|
||||
if (status ?? "") == "OK" {
|
||||
let model = data.content
|
||||
if (data.code ?? 0) == 200 {
|
||||
let model = data.data
|
||||
completion(.success(model))
|
||||
} else {
|
||||
var toastMsg = autoShowErrMsg
|
||||
|
||||
if code == .tokenExpired || code == .tokenIllegal || code == .accountIsFrozen || code == .sign_usernotexist || code == .sign_usernotLoggedIn || code == .sign_userLoginclientNotExist || code == .sign_userNotAuthorizedClient {
|
||||
// ⚠️ 弹出登陆
|
||||
UserCore.shared.logout()
|
||||
|
||||
if let Vc = UIWindow.getTopViewController(), (Vc is CLLoginMainController || Vc is PersonalInformationFillController) {
|
||||
// do nothing.
|
||||
} else {
|
||||
// AppRouter.goBackRootController(jumpIndex: .home) {
|
||||
// NotificationCenter.post(name: .presentSignInVc, object: nil, userInfo: nil)
|
||||
// var toastMsg = autoShowErrMsg
|
||||
//
|
||||
// if code == .tokenExpired || code == .tokenIllegal || code == .accountIsFrozen || code == .sign_usernotexist || code == .sign_usernotLoggedIn || code == .sign_userLoginclientNotExist || code == .sign_userNotAuthorizedClient {
|
||||
// // ⚠️ 弹出登陆
|
||||
// UserCore.shared.logout()
|
||||
//
|
||||
// if let Vc = UIWindow.getTopViewController(), (Vc is CLLoginMainController || Vc is PersonalInformationFillController) {
|
||||
// // do nothing.
|
||||
// } else {
|
||||
//// AppRouter.goBackRootController(jumpIndex: .home) {
|
||||
//// NotificationCenter.post(name: .presentSignInVc, object: nil, userInfo: nil)
|
||||
//// }
|
||||
// NotificationCenter.post(name: .presentSignInVc, object: nil, userInfo: nil)
|
||||
// }
|
||||
// } else if code == .newAccount {
|
||||
// // ⚠️ 不进行Toast的Msg类型
|
||||
// toastMsg = false
|
||||
// } else if code == .insufficentCoin {
|
||||
// // ⚠️钱包余额不足
|
||||
// // refresh wallet
|
||||
// toastMsg = false
|
||||
//
|
||||
// var handled = false
|
||||
// if let cow = target as? AICowAPI{
|
||||
// switch cow{
|
||||
// case .voiceCallOperate, .voiceAsr2, .voiceTts:
|
||||
// IMAIViewModel.shared.showChatModelInsufficentCoinSheet()
|
||||
// handled = true
|
||||
// default:
|
||||
// break
|
||||
// }
|
||||
NotificationCenter.post(name: .presentSignInVc, object: nil, userInfo: nil)
|
||||
}
|
||||
} else if code == .newAccount {
|
||||
// ⚠️ 不进行Toast的Msg类型
|
||||
toastMsg = false
|
||||
} else if code == .insufficentCoin {
|
||||
// ⚠️钱包余额不足
|
||||
// refresh wallet
|
||||
toastMsg = false
|
||||
|
||||
var handled = false
|
||||
if let cow = target as? AICowAPI{
|
||||
switch cow{
|
||||
case .voiceCallOperate, .voiceAsr2, .voiceTts:
|
||||
IMAIViewModel.shared.showChatModelInsufficentCoinSheet()
|
||||
handled = true
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
if handled == false{
|
||||
// 弹出充值Sheet
|
||||
CLPurchase.shared.showIAPBuyCoinSheet()
|
||||
}
|
||||
}
|
||||
|
||||
if toastMsg, let msgUnpack = msg, msgUnpack.count > 0 {
|
||||
UIWindow.getTopDisplayWindow()?.makeToast(msgUnpack)
|
||||
}
|
||||
|
||||
dlog("⛔️error: code = \(code ?? .common), msg = \(data.errorMsg ?? "业务状态失败")")
|
||||
completion(.failure(.serviceError(code: code, msg: msg)))
|
||||
// }
|
||||
// if handled == false{
|
||||
// // 弹出充值Sheet
|
||||
// CLPurchase.shared.showIAPBuyCoinSheet()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if toastMsg, let msgUnpack = msg, msgUnpack.count > 0 {
|
||||
// UIWindow.getTopDisplayWindow()?.makeToast(msgUnpack)
|
||||
// }
|
||||
//
|
||||
// dlog("⛔️error: code = \(code ?? .common), msg = \(data.errorMsg ?? "业务状态失败")")
|
||||
// completion(.failure(.serviceError(code: code, msg: msg)))
|
||||
}
|
||||
|
||||
} catch {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
//
|
||||
// RoleApi.swift
|
||||
// Visual_Novel_iOS
|
||||
//
|
||||
// Created by mh on 2025/11/6.
|
||||
//
|
||||
|
||||
import Moya
|
||||
|
||||
let RoleProvider = APIConfig.useMock && UserAPI.useMock
|
||||
? MoyaProvider<RoleAPI>(endpointClosure: myEndpointClosure, stubClosure: { target in
|
||||
let data = target.sampleData
|
||||
if(data.count > 0){
|
||||
return .delayed(seconds: 0.5)
|
||||
}else{
|
||||
return .never
|
||||
}
|
||||
})
|
||||
: MoyaProvider<RoleAPI>(requestClosure: myRequestClosure)
|
||||
|
||||
enum RoleAPI {
|
||||
static let useMock: Bool = false
|
||||
|
||||
// 查询角色列表
|
||||
case characterList(params: [String: Any])
|
||||
|
||||
}
|
||||
|
||||
extension RoleAPI: TargetType {
|
||||
var method: Moya.Method {
|
||||
return .post
|
||||
}
|
||||
|
||||
var task: Task {
|
||||
var mParams = [String: Any]()
|
||||
switch self {
|
||||
case .characterList(let params):
|
||||
// 将传入的参数赋值给 mParams
|
||||
mParams = params
|
||||
}
|
||||
return .requestParameters(parameters: mParams, encoding: JSONEncoding.default)
|
||||
}
|
||||
|
||||
var headers: [String : String]? {
|
||||
return APIConfig.apiHeaders()
|
||||
}
|
||||
|
||||
var baseURL: URL {
|
||||
// 确保 URL 格式正确,避免强制解包导致的崩溃
|
||||
guard let url = URL(string: APIConfig.role) else {
|
||||
fatalError("Invalid baseURL: \(APIConfig.role)")
|
||||
}
|
||||
return url
|
||||
}
|
||||
|
||||
var path: String {
|
||||
switch self {
|
||||
case .characterList:
|
||||
return "/character/list"
|
||||
}
|
||||
}
|
||||
|
||||
var sampleData: Data {
|
||||
switch self {
|
||||
case .characterList:
|
||||
return Data()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
//
|
||||
// ChatRoleViewModel.swift
|
||||
// Visual_Novel_iOS
|
||||
//
|
||||
// Created by mh on 2025/11/6.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CodableWrappers
|
||||
|
||||
// request
|
||||
struct RoleListRequest: Codable {
|
||||
var index = 1
|
||||
var limit = 20
|
||||
var name: String = ""
|
||||
var sourceId = 0
|
||||
var tagId: Int?
|
||||
}
|
||||
|
||||
// model
|
||||
struct RoleListModel: Codable {
|
||||
var total: Int = 0
|
||||
var index: Int = -1
|
||||
var rows: [RoleItem] = []
|
||||
}
|
||||
|
||||
struct RoleItem: Codable {
|
||||
var id: Int = 0
|
||||
var name: String = ""
|
||||
var coverImage: String = ""
|
||||
var updateTime: String = ""
|
||||
var sourceId: Int = 0
|
||||
}
|
||||
|
||||
class ChatRoleViewModel {
|
||||
|
||||
func loadRoles(index: Int, limit: Int = 20, name: String = "", sourceId: Int = -1, tagId: Int? = nil, completion: ((_ datas: [RoleListModel]?) -> Void)?) {
|
||||
var req = RoleListRequest()
|
||||
req.index = index
|
||||
req.limit = limit
|
||||
req.name = name
|
||||
req.sourceId = sourceId
|
||||
req.tagId = tagId
|
||||
|
||||
let params = req.toNonNilDictionary()
|
||||
|
||||
// 根据 API 响应格式,返回的是单个 RoleListModel 对象,而不是数组
|
||||
// 但为了保持接口一致性,我们将单个对象包装成数组
|
||||
RoleProvider.request(.characterList(params: params), modelType: RoleListModel.self) { result in
|
||||
switch result {
|
||||
case .success(let model):
|
||||
// 如果返回的是单个 RoleListModel,将其包装成数组
|
||||
if let model = model {
|
||||
completion?([model])
|
||||
} else {
|
||||
completion?(nil)
|
||||
}
|
||||
case .failure(let failure):
|
||||
dlog("⛔️ 加载角色列表失败: \(failure)")
|
||||
completion?(nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -189,11 +189,6 @@ extension ChatSettingSwipeView {
|
|||
|
||||
extension ChatSettingSwipeView: UITableViewDelegate, UITableViewDataSource {
|
||||
|
||||
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||
// 确保tableView内容可以滑动到最顶部
|
||||
// 不需要额外的contentInset调整
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
guard let imageRow = rows[indexPath.section][indexPath.row] as? ImageRow,
|
||||
imageRow.showArrow else { return }
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ import Combine
|
|||
class RolesRootPageController: CLTabRootController<RolesRootPageView> {
|
||||
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
var page: Int = 1
|
||||
var viewModel: ChatRoleViewModel = ChatRoleViewModel()
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
|
@ -29,6 +31,11 @@ class RolesRootPageController: CLTabRootController<RolesRootPageView> {
|
|||
setupEvent()
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
loadData()
|
||||
}
|
||||
|
||||
private func setupViews() {
|
||||
navigationView.bgView.alpha = 0
|
||||
navigationView.setupBgViewToStatusBarHeight()
|
||||
|
|
@ -44,6 +51,18 @@ class RolesRootPageController: CLTabRootController<RolesRootPageView> {
|
|||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
func loadData() {
|
||||
// if page == 1{
|
||||
//// loadedAiIds.removeAll()
|
||||
// }
|
||||
|
||||
viewModel.loadRoles(index: page) { datas in
|
||||
print(datas)
|
||||
print("11111")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 点击顶部 实现跳转
|
||||
private func handleJump(_ target: JumpTarget) {
|
||||
switch target {
|
||||
|
|
|
|||
Loading…
Reference in New Issue