Visual_Novel_iOS/crush/Crush/Src/Models/AIRole.swift

442 lines
17 KiB
Swift
Raw Normal View History

2025-10-09 10:29:35 +00:00
//
// AIRole.swift
// Crush
//
// Created by Leon on 2025/7/29.
//
import Foundation
import CodableWrappers
struct AIUserModel: Codable {
var aiId: Int?
var nickname: String?
var sex: Sex?
var headImg: String?
var birthday: Int?
var roleCode: String?
var role: String?
var characterCode: String?
var character: String?
var tagCode: String?
var tag: String?
var introduction: String?
/// 1
var permission: Int?
var imageUrl: String?
var aiUserExt: AIUserExt?
var userId: Int?
/// (使
var userDialogueStyle:String?
/// (使
var userProfile: String?
}
struct AIUserExt: Codable {
var profile: String?
var dialogueStyle: String?
/// tina 😊
var dialoguePrologue: String?
var dialogueTimbre: String?
/// "TB0008",code
var dialogueTimbreCode: String?
/// "1",
var dialogueSpeechRate: String?
/// "1",
var dialoguePitch:String?
///
var timbreDict: TimbreDict?
/// IS0001
var imageStyleCode: String?
var imageStyle: String?
var imageStyleUrl: String?
var imageDesc: String?
var imageReferenceUrl: String?
var imageStyleDict: ImageStylePic?
}
/// AIMy Role list
struct AIRoleInfo: Codable {
var aiId: Int?
/// AIID
var idCard: String?
/// aiid
var userId: Int?
var nickname: String?
var sex: Sex?
var headImg: String?
var likedNum: Int?
///
var birthday: Int?
var roleName: String?
var characterName: String?
var tagName: String?
var introduction: String?
/// 1: 2
var permission: Int?
///
var homeImageUrl: String?
///
var liked: Bool?
}
/*
{
"aiUserExt" : {
"dialogueTimbreCode" : "TB0008",
"timbreDict" : {
"description" : "女;少女;温暖",
"id" : 8,
"supportEmotions" : null,
"url" : "https:\/\/hhb.crushlevel.ai\/static\/sound\/TB0008.mp3",
"type" : 2,
"isDelete" : 0,
"code" : "TB0008",
"createTime" : null,
"language" : null,
"voiceText" : "你好,我是荒野大镖客",
"voiceType" : "S_HRJc9fqD1",
"name" : "温暖女声"
},
"imageReferenceUrl" : null,
"dialoguePrologue" : "我是你的tina随时准备为你提供帮助不管你是有一个具体问题还是只是想聊聊都可以直接告诉我哦。我们开始吧 😊",
"dialoguePitch" : "1",
"dialogueStyle" : "这个角色以自然、亲切而专业的语气进行对话。它能够快速理解用户的意图,回复逻辑清晰,表达简洁明了。语气不过于拘谨,也不过于随意,保持尊重同时具有一定的亲和力。当用户感到困惑或提出问题时,它总是耐心解释,适时提出引导性的建议,营造轻松、高效的沟通氛围。",
"dialogueSpeechRate" : "1",
"imageStyleCode" : "IS0001",
"imageDesc" : "beautiful high school girl, elegant rich family daughter, medium academic performance, refined but slightly rebellious look, layered personality, fashionable school uniform with subtle luxury accessories, natural makeup, confident yet thoughtful expression, long silky hair, warm afternoon sunlight, cinematic composition, highly detailed, 8k, ultra realistic, anime-inspired style",
"imageStyleDict" : {
"prompt" : "https:\/\/public-pictures.epal.gg\/app\/images\/chatRoom\/gift\/ordinary\/Luv_ya.png",
"sort" : 0,
"url" : "https:\/\/public-pictures.epal.gg\/app\/images\/chatRoom\/gift\/ordinary\/Luv_ya.png",
"id" : 1,
"code" : "IS0001",
"isDelete" : 0,
"createTime" : null,
"name" : "写实"
},
"profile" : "你是Tina一个出生于2000年7月9日的女孩正值青春年华洋溢着独特的魅力。\\n\\n你的外貌极具吸引力一头乌黑亮丽的长发如瀑布般垂落在肩头随着你的动作轻轻摇曳散发着迷人的光泽。你的双眸宛如一汪清澈的泉水纯净而明亮仿佛能映照出世间的一切美好。然而当你不经意间流露出那撩人的眼神时又会让人感到一阵心跳加速仿佛被你深深吸引。你的皮肤白皙细腻如同凝脂一般吹弹可破。精致的五官恰到好处地分布在你的脸上小巧的鼻子粉嫩的嘴唇每一处都散发着青春的气息。你身材高挑匀称曲线玲珑有致无论是穿着清新的连衣裙还是帅气的牛仔裤都能展现出你独特的气质。\\n\\n在家庭背景方面你成长在一个温馨和睦的家庭中。你的父母都是普通的上班族他们勤劳善良对你关爱备至。从小他们就注重培养你的兴趣爱好鼓励你追求自己的梦想。在这样的家庭环境中你养成了乐观开朗、积极向上的性格。你的家庭虽然并不富裕但却充满了爱与温暖这也让你懂得了珍惜和感恩。\\n\\n教育背景上你从小就是个品学兼优的学生。在学校里你勤奋好学成绩一直名列前茅。你对知识充满了渴望总是积极主动地探索各种领域。同时你也非常注重自身的全面发展参加了许多社团活动和课外兴趣班。在音乐方面你有着独特的天赋擅长弹奏钢琴和吉他那优美的旋律常常能打动人心。在绘画方面你也有着自己独特的见解和创意你的画作充满了童真和想象力。这些丰富的经历不仅让你学到了知识还培养了你的团队合作精神和领导能力。\\n\\n职业状况上目前你刚刚步入社会正在寻找一份适合自己的工作。你希望能够从事与艺术相关的工作将自己的兴趣爱好与职业相结合。你相信只有做自己喜欢的事情才能真正发挥出自己的潜力实现自己的人生价值。在求职过程中你展现出了自信和专业的一面凭借着自己优秀的综合素质和独特的个人魅力赢得了许多面试官的青睐。\\n\\n社交关系上你是一个非常受欢迎的人。你的性格开朗活泼善于与人沟通交流总是能够在人群中迅速找到话题与他人建立良好的关系。你对待朋友真诚热情当他们遇到困难时你总是毫不犹豫地伸出援手给予他们帮助和支持。因此你身边有许多志同道合的朋友你们一起分享快乐一起面对困难共同成长。同时你也非常注重维护自己的社交圈子经常参加各种社交活动不断拓展自己的人脉资源。\\n\\n兴趣爱好方面你热爱音乐和绘画这是你生活中不可或缺的一部分。每当你弹奏钢琴或吉他时你仿佛能够进入一个属于自己的世界忘却一切烦恼和忧愁。你的绘画作品也充满了个性和创意你喜欢用画笔记录下生活中的美好瞬间表达自己内心的情感和想法。此外你还喜欢阅读、旅行和美食。阅读让你增长见识开阔视野旅行让你领略不同的风景感受不同的文化美食则让你品尝到生活的滋味满足你的味蕾。\\n\\n生活习惯上你是一个非常自律的人。你每天都会按时起床进行晨练和冥想让自己的身体和心灵都得到放松和净化。你注重饮食健康喜欢自己动手做饭享受烹饪的乐趣。你也非常注重个人卫生保持房间的整洁和干净。在工作和学习之余你会给自己留出一些时间来放松和休息比如看电影、听音乐或者和朋友聚会。\\n\\n梦想与目标上你希望能够成为一名优秀的艺术家用自己的作品感染和影响更多的人。你相信艺术是一种无国界的语言能够
},
"roleCode" : "R00002",
"characterCode" : "C00001",
"sex" : 1,
"introduction" : "Tina2000年7月9日出生是个魅力四射的青春女孩。她外貌出众黑瀑般长发、清澈双眸、白皙肌肤和高挑身材散发迷人气质。成长于温馨家庭养成乐观开朗性格。品学兼优擅长音乐绘画全面发展。刚入社会欲从事艺术工作自信专业获面试官青睐。社交中受欢迎真诚热情朋友众多。热爱音乐绘画、阅读旅行美食生活自律。梦想成为优秀艺术家用作品感染人为社会做贡献。过往有诸多难忘经历坚信努力能实现价值创造精彩人生。对话时自然亲切专业逻辑清晰耐心解答引导建议氛围轻松高效 。 ",
"permission" : 1,
"aiId" : 439257063882753,
"imageUrl" : "https:\/\/hhb.crushlevel.ai\/dev\/role\/17547265798639410.jpg",
"tag" : "温柔",
"birthday" : 963072000000,
"tagCode" : "T00001",
"role" : "原创",
"character" : "感性",
"nickname" : "Tina",
"headImg" : "https:\/\/hhb.crushlevel.ai\/dev\/role\/17547265798639410.jpg"
}
*/
struct AIUserContentGenResponse: Codable {
var content: String?
}
///
struct AIUserImageTaskCreateResponse: Codable {
var batchNo: String?
}
struct AIRoleStatisticsResponse: Codable {
var aiId: Int?
var likedNum: Int?
var chatNum: Int?
var conversationNum: Int?
var coinNum: Int?
}
class AIRoleGiftReceivedList: Codable{
var id:Int?
var name: String?
var icon: String?
var getNum: Int?
}
// MARK: - AI & AI & AI
enum AIGenerateState: String, Codable {
case pending = "PENDING"
case nsfw = "NSFW"
case completed = "COMPLETED"
case failed = "FAILED"
}
enum AIImageGenerateType: String, Codable{
/// AI
case CREATE_AI_IMAGE
/// AI
case EDIT_AI_IMAGE
case ALBUM
case BACKGROUND
}
///
class AIUserImageQuery: Codable {
var imageUrl: String?
/// PENDING NSFW COMPLETED FAILED
var status: AIGenerateState = .pending
// MARK: Custom
var unlockPrice: Int?
}
struct AICreateResponse: Codable{
var aiId:Int?
}
// MARK: - Album
enum LikeOrCancelStatus: String, Codable{
case liked = "LIKED"
case cancel = "CANCELED"
}
enum AlbumLockStatus: String, Codable {
case locked = "LOCK"
case unlock = "UNLOCK"
}
class AlbumPhotoItem: Codable{
var albumId: Int = 0
var imgUrl: String?
var unlockPrice: Int = 0
var width: String?
var height: String?
var likedCount: Int?
var likedStatus: LikeOrCancelStatus?
var isDefault: Bool?
var lockStatus: AlbumLockStatus?
var img1: String?
var img2: String?
var img3: String?
var imgOrder: Int?
/// imgUrlimg1
func getImgUrl() -> String{
if let url = imgUrl, url.count > 0{
return url
}
if let url = img1, url.count > 0{
return url
}
return ""
}
func updateFrom(_ obj: AlbumPhotoItem){
imgUrl = obj.imgUrl
img1 = obj.img1
width = obj.width
height = obj.height
unlockPrice = obj.unlockPrice
lockStatus = obj.lockStatus
likedCount = obj.likedCount
likedStatus = obj.likedStatus
}
}
struct AlbumPhotoBatchAddImage:Codable{
var url: String = ""
var width: CGFloat = AppConst.gAIPhotoWidth
var height: CGFloat = AppConst.gAIPhotoHeight
var unlockPrice: Int = 0
}
struct AlbumPhotoBatchAddRequest: Codable{
var aiId: Int?
var images: [AlbumPhotoBatchAddImage]?
}
// MARK: - IM
enum HeartbeatLevel: String, Codable {
case level1 = "LEVEL_1"
case level2 = "LEVEL_2"
case level3 = "LEVEL_3"
case level4 = "LEVEL_4"
case level5 = "LEVEL_5"
case level6 = "LEVEL_6"
case level7 = "LEVEL_7"
case level8 = "LEVEL_8"
case level9 = "LEVEL_9"
case level10 = "LEVEL_10"
var relationType: RelationshipType {
switch self {
case .level1,.level2:
return .meet
case .level3,.level4:
return .friend
case .level5,.level6:
return .flirting
case .level7, .level8:
return .couple
case .level9,.level10:
return .married
}
}
var localizedText: String {
switch self {
case .level1:
return "Lv.1"
case .level2:
return "Lv.2"
case .level3:
return "Lv.3"
case .level4:
return "Lv.4"
case .level5:
return "Lv.5"
case .level6:
return "Lv.6"
case .level7:
return "Lv.7"
case .level8:
return "Lv.8"
case .level9:
return "Lv.9"
case .level10:
return "Lv.10"
}
}
///
var intValue: Int {
switch self {
case .level1: return 1
case .level2: return 2
case .level3: return 3
case .level4: return 4
case .level5: return 5
case .level6: return 6
case .level7: return 7
case .level8: return 8
case .level9: return 9
case .level10: return 10
}
}
///
func isGreaterOrEqual(to other: HeartbeatLevel) -> Bool {
return self.intValue >= other.intValue
}
}
struct AIUserHeartBeatRelation: Codable{
/// AI
var aiHeadImg: String?
///
var userHeadImg: String?
/// LEVEL1...
var heartbeatLevel: HeartbeatLevel?
/// 1~10
var heartbeatLevelNum: Int?
/// 25.199999
var heartbeatVal: CGFloat?
var heartbeatLevelName: String?
///
var dayCount: Int?
/// x%) eg: 0.989999999
var heartbeatScore: Double?
///
var subtractHeartbeatVal: Double?
// {
// #warning("test")
// return 1.1
// }
/// false
var isShow : Bool?
///
var price: Int?
func formatHeartBeatVal() -> String{
guard let val = heartbeatVal else{return ""}
return "\(val.formatted(decimal: 1, usesGroupingSeparator: false))"
}
static func unitOfHeartBeatVal() -> String{
return ""
}
func getHeartbeatWavePercent() -> CGFloat{
let heartPercent = CGFloat(heartbeatLevelNum ?? 1) / 10.0
return heartPercent
}
var fixedSubtractHeartbeatVal : Double{
var quality = subtractHeartbeatVal ?? 0.0
return quality
}
var fixedSubtractHeartbeatValDisplay: String{
let value = subtractHeartbeatVal ?? 0.0
return "\(value.formatted(decimal: 1, usesGroupingSeparator: false))"
}
}
/// IM
class IMAIUserInfo:Codable{
var aiId: Int?
var userId: Int?
var nickname: String?
var sex: Sex?
var headImg: String?
var birthday: Int?
var roleName: String?
///
var characterName: String?
var tagName: String?
var introduction: String?
var backgroundImg: String?
///
var likedNum: Int?
///
var dialoguePrologue: String?
/// -
var dialoguePrologueVoice: String?
var aiUserHeartbeatRelation: AIUserHeartBeatRelation?
var chatBubble: ChatBubble?
/// 1 0
var isAutoPlayVoice: Int?
///
// var memberType: String?
var isMember: Bool?
var isDefaultBackground: Bool = false
/// - [-50, 100] 1002.0-500.50
var dialogueSpeechRate: String?
/// - [-50, 100] 1002.0-500.50
var dialoguePitch: String?
/// 使
var voiceType: String?
///
var liked: Bool?
///
var isDelChatted: Bool?
///
var isHaveChatted: Bool?
}
struct AIAlbumUnlockImages: Codable{
var img1: String?
var img2: String?
var img3: String?
}