// // AIRoleApi.swift // Crush // // Created by Leon on 2025/7/29. // import Moya let AIRoleProvider = APIConfig.useMock && AIRoleAPI.useMock ? MoyaProvider(endpointClosure: myEndpointClosure, stubClosure: { target in let data = target.sampleData if data.count > 0 { return .delayed(seconds: 0.5) } else { return .never } }) : MoyaProvider(requestClosure: myRequestClosure) enum AIRoleAPI { static let useMock: Bool = true /// 创建或编辑AI case aiUserCreateEdit(params: [String: Any]) /// 我的AI角色删除 case aiDel(id:Int) /// 我的AI信息查询, 🔥编辑时使用 case aiInfoMineGet(id:Int) /// 单独的修改AI头像接口 case modifyAIAvatar(aiId: Int, userHead: String) // MARK: AI Role query /// 获取AI基础信息(基础查询) case queryAIBaseInfo(aiId: Int) /// 获取自己的AI列表 case aiRoleListOfMine /// 目标用户的AI列表 case aiRoleListOfOther(userId: Int) case aiUserLikeOrCancel(aiId: Int, likedStatus: LikeOrCancelStatus) // MARK: Other Info /// 获取AI信息统计信息 case aiRoleStatistics(aiId: Int) /// 获取用户获得的礼物列表 case aiRoleGotGiftList(params: [String: Any]) // MARK: Album case aiRoleAlbumList(params: [String: Any]) case aiRoleAlbumDel(userId:Int?, albumId:Int?) case aiRolePhotoLikeOrNo(albumId:Int?, likedStatus: LikeOrCancelStatus?) case aiRolePhotoDefaultSet(aiUid:Int?, albumId:Int?) case aiRoleBatchAddAlbum(params: [String: Any]) case aiRolePhotoUnlockPriceSet(aiUid:Int?, albumId:Int?, unlockPrice:Int = 0) // MARK: IM User info case imUserBaseInfo(aiId:Int) /// 加密图片解锁后访问 case imUnlockAlbumImgToBrowse(params: [String: Any]) /// 解锁加密图片 case imUnlockAlbumImg(params: [String: Any]) // MARK: Relation level case heartBeatRelationSwitch(aiId: Int, isShow: Bool) /// 24小时未聊天扣除心动值,登陆后调用一次 case heartBeatSubtractLanuchActiveOnce /// 心动等级获取 case heartBeatLevelGet(aiId: Int) /// 购买心动值数量 case heartBeatPurchase(aiId: Int, heartBeatVal: CGFloat) case heartBeatRankGet // MARK: Chat background case batchAddChatBackground(params: [String: Any]) case getChatBackgroundList(aiId: Int) case setDefaultChatBackground(params: [String: Any]) case deleteChatBackground(backgroundId: Int) // MARK: Chat setup case chatSetupGet(aiId: Int) case chatSetAutoPlayVoice(aiId: Int, isAutoPlayVoice: Bool) case chatSetup(params: [String: Any]) case chatModelSetup(params: [String: Any]) case chatBubbleSetup(params: [String: Any]) } extension AIRoleAPI: TargetType { var baseURL: URL { return URL(string: APIConfig.frog)! } var path: String { switch self { case .aiUserCreateEdit: return "/web/ai-user/create-edit" case .aiDel: return "/web/ai-user/del" case .aiInfoMineGet: return "/web/ai-user/get-my-ai-user/info" case .modifyAIAvatar: return "/web/ai-user/edit-head-img" case .queryAIBaseInfo: return "/web/ai-user-search/base-info" case .aiRoleListOfMine: return "/web/ai-user-search/base-list" case .aiRoleListOfOther: return "/web/ai-user-search/target-list" case .aiUserLikeOrCancel: return "/web/ai-user/like-or-cancel" case .aiRoleStatistics: return "/web/ai-user/stat" case .aiRoleGotGiftList: return "/web/ai-user-gift/list" case .aiRoleAlbumList: return "/web/ai-user/album-list" case .aiRoleAlbumDel: return "/web/ai-user/album-del" case .aiRolePhotoLikeOrNo: return "/web/album/like_or_cancel" case .aiRolePhotoDefaultSet: return "/web/ai-user/set-default-album" case .aiRoleBatchAddAlbum: return "/web/ai-user/batch-add-album" case .aiRolePhotoUnlockPriceSet: return "/web/ai-user/set-album-unlock-price" case .imUserBaseInfo: return "/web/ai-user-search/im-base-info" case .imUnlockAlbumImgToBrowse: return "/web/ai-user/view-unlock-album-img" case .imUnlockAlbumImg: return "/web/ai-user/unlock-album-img" case .heartBeatRelationSwitch: return "/web/ai-user/heartbeat-relation-switch" case .heartBeatSubtractLanuchActiveOnce: return "/web/ai-user/without-chat-subtract-heartbeat-val" case .heartBeatLevelGet: return "/web/ai-user/heartbeat-level" case .heartBeatPurchase: return "/web/ai-user/buy-heartbeat-val" case .heartBeatRankGet: return "/web/ai-user/heartbeat-rank" case .batchAddChatBackground: return "/web/chat-background/batch-add" case .getChatBackgroundList: return "/web/chat-background/list" case .setDefaultChatBackground: return "/web/chat-background/set-background" case .deleteChatBackground: return "/web/chat-background/del" case .chatSetupGet: return "/web/chat-set/get-my" case .chatSetAutoPlayVoice: return "/web/chat-set/auto-play-voice" case .chatSetup: return "/web/chat-set/set" case .chatModelSetup: return "/web/chat-set/set-chat-model" case .chatBubbleSetup: return "/web/chat-set/set-chat-bubble" } } var method: Moya.Method { return .post } var task: Task { var mParams = [String: Any]() switch self { case let .aiUserCreateEdit(params): mParams = params case let .aiDel(id): mParams.updateValue(id, forKey: "aiId") case let .aiInfoMineGet(id): mParams.updateValue(id, forKey: "aiId") case let .modifyAIAvatar(aiId, userHead): mParams.updateValue(aiId, forKey: "aiId") mParams.updateValue(userHead, forKey: "userHead") case .queryAIBaseInfo(let aiId): mParams.updateValue(aiId, forKey: "aiId") case .aiRoleListOfMine: break case .aiRoleListOfOther(let userId): mParams.updateValue(userId, forKey: "userId") case .aiUserLikeOrCancel(let aiId, let likedStatus): mParams.updateValue(aiId, forKey: "aiId") mParams.updateValue(likedStatus.rawValue, forKey: "likedStatus") case .aiRoleStatistics(let aiId): mParams.updateValue(aiId, forKey: "aiId") case .aiRoleGotGiftList(let params): mParams = params case .aiRoleAlbumList(let params): mParams = params case .aiRoleAlbumDel(let userId, let albumId): mParams.updateValue(userId ?? 0, forKey: "userId") mParams.updateValue(albumId ?? 0, forKey: "albumId") case .aiRolePhotoLikeOrNo(let albumId , let likedStatus): mParams.updateValue((likedStatus ?? .liked).rawValue, forKey: "likedStatus") mParams.updateValue(albumId ?? 0, forKey: "albumId") case .aiRolePhotoDefaultSet(let aiUid, let albumId): mParams.updateValue(aiUid ?? 0, forKey: "aiId") mParams.updateValue(albumId ?? 0, forKey: "albumId") case .aiRoleBatchAddAlbum(let params): mParams = params case .aiRolePhotoUnlockPriceSet(let aiUid, let albumId, let unlockPrice): mParams.updateValue(aiUid ?? 0, forKey: "aiId") mParams.updateValue(albumId ?? 0, forKey: "albumId") mParams.updateValue(unlockPrice, forKey: "unlockPrice") case .imUserBaseInfo(let aiId): mParams.updateValue(aiId, forKey: "aiId") case .imUnlockAlbumImgToBrowse(let params): mParams = params case .imUnlockAlbumImg(let params): mParams = params case .heartBeatRelationSwitch(let aiId, let isShow): mParams.updateValue(aiId, forKey: "aiId") mParams.updateValue(isShow, forKey: "isShow") case .heartBeatSubtractLanuchActiveOnce: break case .heartBeatLevelGet(let aiId): mParams.updateValue(aiId, forKey: "aiId") case .heartBeatPurchase(let aiId, let heartBeatVal): mParams.updateValue(aiId, forKey: "aiId") mParams.updateValue(heartBeatVal, forKey: "heartBeatVal") case .heartBeatRankGet: break case .batchAddChatBackground(let params): mParams = params case .getChatBackgroundList(let aiId): mParams.updateValue(aiId, forKey: "aiId") case .setDefaultChatBackground(let params): mParams = params case .deleteChatBackground(let backgroundId): mParams.updateValue(backgroundId, forKey: "backgroundId") case .chatSetupGet(let aiId): mParams.updateValue(aiId, forKey: "aiId") case .chatSetAutoPlayVoice(let aiId, let isAutoPlayVoice): mParams.updateValue(aiId, forKey: "aiId") mParams.updateValue(isAutoPlayVoice, forKey: "isAutoPlayVoice") case .chatSetup(let params): mParams = params case .chatModelSetup(let params): mParams = params case .chatBubbleSetup(let params): mParams = params } mParams.updateValue("IOS", forKey: "appClient") mParams.updateValue(UIDevice.UUID, forKey: "deviceCode") return .requestParameters(parameters: mParams, encoding: JSONEncoding.default) } var headers: [String: String]? { return APIConfig.apiHeaders() } var sampleData: Data { switch self { //🔥创建AI/ Edit AI // case .aiUserCreateEdit: // let content = """ // { // "aiId" : 437416915828737 // } // """ // return .okContent(string: content ) // case .aiDel: // return .okData() // case .aiInfoMineGet: // return .aiMockInfo() // case .imageGenerateCreateTask: // let content = """ // { // "batchNo": "XXXEEE" // } // """ // return .okContent(string: content) // case .imageGeneratedQuery: // let content = """ // [{ // "imageUrl": "https://fastly.picsum.photos/id/871/400/400.jpg?hmac=2DvXsmLSHy27AnVwE2ceSGeY7SmL9gg-WYgEckt8fCQ", // "status": "COMPLETED" // }, // { // "imageUrl": "https://fastly.picsum.photos/id/301/200/200.jpg?hmac=8LBy-lxo8NF1vIabeRaqqBVpr2XpkwTzOSpicYy8YSU", // "status": "COMPLETED" // }, // { // "imageUrl": "https://fastly.picsum.photos/id/544/400/400.jpg?hmac=ErjxMQaSKPgH0-3sMYxdrBN9Qy8Xz8VEVd9ZtVoJEUU", // "status": "COMPLETED" // }, // { // "imageUrl": "https://fastly.picsum.photos/id/973/400/400.jpg?hmac=wLkchQD9lw5rv7FCDVlc2n2s8IB-sGw_8VN1ASZg74g", // "status": "COMPLETED" // }, // { // "imageUrl": "https://fastly.picsum.photos/id/611/400/400.jpg?hmac=dqUFohQSDmf7SOKUoEBL6RhPD7WY9RyxRYlhgZoc4zY", // "status": "COMPLETED" // }, // ] // """ // return .okContent(string: content) // case .queryAIBaseInfo: // let content = """ // { // "aiId": 123456789, // "idCard": "AI-000998", // "nickname": "虚拟小可", // "userId" : 3140, // "sex": 1, // "headImg": "https://fastly.picsum.photos/id/324/400/400.jpg?hmac=FNvSnDH2LM9s_74wXGut5LXk2W3XavYhnxsSWmrJlqg", // "birthday": "2001-05-20", // "roleName": "治愈系AI", // "characterName": "温柔体贴", // "tagName": "心理陪伴", // "introduction": "我是你永远的AI朋友,随时陪伴在你左右。", // "permission": 1, // "homeImageUrl": "https://fastly.picsum.photos/id/324/400/400.jpg?hmac=FNvSnDH2LM9s_74wXGut5LXk2W3XavYhnxsSWmrJlqg" // } // """ // return .okContent(string: content) // case .aiRoleListOfMine: // let content = """ // [{ // "aiId": 123456789, // "idCard": "AI-000998", // "userId" : 3140, // "nickname": "虚拟小可", // "sex": 1, // "headImg": "https://fastly.picsum.photos/id/324/400/400.jpg?hmac=FNvSnDH2LM9s_74wXGut5LXk2W3XavYhnxsSWmrJlqg", // "birthday": "2001-05-20", // "roleName": "治愈系AI", // "characterName": "温柔体贴", // "tagName": "心理陪伴", // "introduction": "我是你永远的AI朋友,随时陪伴在你左右。", // "permission": 1, // "homeImageUrl": "https://fastly.picsum.photos/id/324/400/400.jpg?hmac=FNvSnDH2LM9s_74wXGut5LXk2W3XavYhnxsSWmrJlqg" // } // ] // """ // return .okContent(string: content) // case .aiRoleStatistics: // let content = """ // { // "aiId": 987654321, // "likedNum": 1234, // "chatNum": 5678, // "conversationNum": 4321, // "coinNum": 876faiRolePhotoLikeOrNo // } // """ // return .okContent(string: content) // case .aiRoleAlbumList: // let content = """ // [{ // "albumId": 1, // "imgUrl": "https://fastly.picsum.photos/id/418/400/400.jpg?hmac=bb10nb5u-sK8fxD4fyTmZO36Q4N6jRTuSj-ChqtM_3M", // "unlockPrice": 12, // "width": "400", // "height": "400", // "likedCount": 10, // "likedStatus": "CANCELED", // "isDefault": true, // "lockStatus": "LOCK", // "img1": "", // "img2": "", // "img3": "", // "imgOrder": 0 // }, // { // "albumId": 2, // "imgUrl": "https://fastly.picsum.photos/id/822/400/400.jpg?hmac=poBkUx6CibkZhMJfqWvaKR8uk8GbT5FC9ShX5oMGOr4", // "unlockPrice": 12, // "width": "400", // "height": "400", // "likedCount": 10, // "likedStatus": "LIKED", // "isDefault": false, // "lockStatus": "UNLOCK", // "img1": "", // "img2": "", // "img3": "", // "imgOrder": 0 // } // ] // """ // return .okPageDatas(string: content) // case .aiRoleAlbumDel: // return .okData() // case .aiRolePhotoLikeOrNo: // return .okData() // case .aiRolePhotoDefaultSet: // return .okData() // case .aiRoleBatchAddAlbum: // return .okData() // case .heartBeatRankGet: // let json = """ // { // "status" : "OK", // "errorCode" : null, // "content" : 0.9, // "errorMsg" : null, // "traceId" : "a87240e3-f7a3-4a02-89fc-be4c54d37a86" // } // """ // return Data(json.utf8) default: return Data() } } }