Commit 35aef122 authored by Steven杜宇's avatar Steven杜宇

// AI

parent 0ba27ffe
...@@ -667,6 +667,7 @@ ...@@ -667,6 +667,7 @@
04B9EE5A2C06CC3100A4018D /* YHCodeSueecssViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04B9EE582C06CC3100A4018D /* YHCodeSueecssViewController.swift */; }; 04B9EE5A2C06CC3100A4018D /* YHCodeSueecssViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04B9EE582C06CC3100A4018D /* YHCodeSueecssViewController.swift */; };
04B9EE5B2C06CC3100A4018D /* YHOtherLoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04B9EE592C06CC3100A4018D /* YHOtherLoginViewController.swift */; }; 04B9EE5B2C06CC3100A4018D /* YHOtherLoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04B9EE592C06CC3100A4018D /* YHOtherLoginViewController.swift */; };
04BD83452CCA2009003A88DF /* AlimamaShuHeiTi-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 04BD83442CCA2009003A88DF /* AlimamaShuHeiTi-Bold.ttf */; }; 04BD83452CCA2009003A88DF /* AlimamaShuHeiTi-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 04BD83442CCA2009003A88DF /* AlimamaShuHeiTi-Bold.ttf */; };
04BE39282CF848F300BD31DB /* YHAIMessageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04BE39272CF848F300BD31DB /* YHAIMessageModel.swift */; };
04C693622B723AB8004C1758 /* YHMySettingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04C693612B723AB8004C1758 /* YHMySettingViewController.swift */; }; 04C693622B723AB8004C1758 /* YHMySettingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04C693612B723AB8004C1758 /* YHMySettingViewController.swift */; };
04C693642B723B56004C1758 /* YHMySettingCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04C693632B723B56004C1758 /* YHMySettingCell.swift */; }; 04C693642B723B56004C1758 /* YHMySettingCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04C693632B723B56004C1758 /* YHMySettingCell.swift */; };
04C85DDF2C364FE9008B20D6 /* YHAboutUsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04C85DDE2C364FE9008B20D6 /* YHAboutUsCell.swift */; }; 04C85DDF2C364FE9008B20D6 /* YHAboutUsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04C85DDE2C364FE9008B20D6 /* YHAboutUsCell.swift */; };
...@@ -1716,6 +1717,7 @@ ...@@ -1716,6 +1717,7 @@
04B9EE582C06CC3100A4018D /* YHCodeSueecssViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = YHCodeSueecssViewController.swift; sourceTree = "<group>"; }; 04B9EE582C06CC3100A4018D /* YHCodeSueecssViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = YHCodeSueecssViewController.swift; sourceTree = "<group>"; };
04B9EE592C06CC3100A4018D /* YHOtherLoginViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = YHOtherLoginViewController.swift; sourceTree = "<group>"; }; 04B9EE592C06CC3100A4018D /* YHOtherLoginViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = YHOtherLoginViewController.swift; sourceTree = "<group>"; };
04BD83442CCA2009003A88DF /* AlimamaShuHeiTi-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "AlimamaShuHeiTi-Bold.ttf"; sourceTree = "<group>"; }; 04BD83442CCA2009003A88DF /* AlimamaShuHeiTi-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "AlimamaShuHeiTi-Bold.ttf"; sourceTree = "<group>"; };
04BE39272CF848F300BD31DB /* YHAIMessageModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHAIMessageModel.swift; sourceTree = "<group>"; };
04C693612B723AB8004C1758 /* YHMySettingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHMySettingViewController.swift; sourceTree = "<group>"; }; 04C693612B723AB8004C1758 /* YHMySettingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHMySettingViewController.swift; sourceTree = "<group>"; };
04C693632B723B56004C1758 /* YHMySettingCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHMySettingCell.swift; sourceTree = "<group>"; }; 04C693632B723B56004C1758 /* YHMySettingCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHMySettingCell.swift; sourceTree = "<group>"; };
04C85DDE2C364FE9008B20D6 /* YHAboutUsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHAboutUsCell.swift; sourceTree = "<group>"; }; 04C85DDE2C364FE9008B20D6 /* YHAboutUsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHAboutUsCell.swift; sourceTree = "<group>"; };
...@@ -3953,6 +3955,7 @@ ...@@ -3953,6 +3955,7 @@
children = ( children = (
045F28492CF6F5B100520F19 /* YHAIViewModel.swift */, 045F28492CF6F5B100520F19 /* YHAIViewModel.swift */,
045F284B2CF6F65200520F19 /* YHAIListModel.swift */, 045F284B2CF6F65200520F19 /* YHAIListModel.swift */,
04BE39272CF848F300BD31DB /* YHAIMessageModel.swift */,
); );
path = M; path = M;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -5893,6 +5896,7 @@ ...@@ -5893,6 +5896,7 @@
045EEEBF2B9F171A0022A143 /* YHWorkFileItemView.swift in Sources */, 045EEEBF2B9F171A0022A143 /* YHWorkFileItemView.swift in Sources */,
04AF58C42B4FC51C0066011A /* YHLocalizable.swift in Sources */, 04AF58C42B4FC51C0066011A /* YHLocalizable.swift in Sources */,
0457921F2CBF62F300EBD99B /* YHResignUploadDetailModel.swift in Sources */, 0457921F2CBF62F300EBD99B /* YHResignUploadDetailModel.swift in Sources */,
04BE39282CF848F300BD31DB /* YHAIMessageModel.swift in Sources */,
04F4A5282CB8D4270026D469 /* YHResignAppointScheduleListViewController.swift in Sources */, 04F4A5282CB8D4270026D469 /* YHResignAppointScheduleListViewController.swift in Sources */,
A598E9E22C7CB32D00F84739 /* YHTravelDocsPreparationListModel.swift in Sources */, A598E9E22C7CB32D00F84739 /* YHTravelDocsPreparationListModel.swift in Sources */,
A598E9D72C7C9EF300F84739 /* YHTravelDocsPreparationListViewController.swift in Sources */, A598E9D72C7C9EF300F84739 /* YHTravelDocsPreparationListViewController.swift in Sources */,
......
...@@ -43,7 +43,7 @@ class YHAIChatViewController: YHBaseViewController { ...@@ -43,7 +43,7 @@ class YHAIChatViewController: YHBaseViewController {
messages.append(question) messages.append(question)
self.scrollToBottom() self.scrollToBottom()
YHAIRequestManager.shared.requestAI(query: text) { YHAIRequestManager.shared.requestAI(botId: "", conversationId: "", question:text) {
[weak self] res in [weak self] res in
guard let self = self else { return } guard let self = self else { return }
self.handleMessage(res) self.handleMessage(res)
......
//
// YHAIMessageModel.swift
// galaxy
//
// Created by Dufet on 2024/11/28.
// Copyright © 2024 https://www.galaxy-immi.com. All rights reserved.
//
import UIKit
import SmartCodable
class YHAIMessageModel: NSObject {
}
enum YHAIResponseType: Int {
case none = 0
case text = 1
case card = 2
}
class YHAIMessage: CustomStringConvertible {
var id: String = ""
var event: String = ""
var data: [String : Any] = [:]
var uuid: String = ""
var isSelf: Bool = false
var body = YHAIResponseBody()
func isFinishd() -> Bool {
if event.isEmpty {
return true
}
if event == "conversation.message.completed" {
return true
}
return false
}
func setFinished() {
event = "conversation.message.completed"
}
static func createQuestion(_ text: String) -> YHAIMessage {
let question = YHAIMessage()
question.isSelf = true
let body = YHAIResponseBody()
body.contentType = 1
body.contentText = text
question.setFinished()
question.body = body
return question
}
func getType() -> YHAIResponseType {
if let type = data["contentType"] as? Int, type == 1 {
return .text
}
return .none
}
func getText() -> String {
if getType() == .text {
if let text = data["contentText"] as? String, !text.isEmpty {
return text
}
}
return ""
}
var description: String {
return "uudi:\(uuid)\n,id: \(id)\n, event: \(event)\n, data: \(data))\n\n"
}
}
class YHAIResponseBody: SmartCodable {
// "contentType":1,"contentText":"如何判断未来深圳的天气走势?","botId":"7439200648601714700","status":"completed"
var contentType: Int = 0
var contentText: String = ""
var botId: String = ""
var status: String = ""
required init() {
}
}
...@@ -10,120 +10,131 @@ import UIKit ...@@ -10,120 +10,131 @@ import UIKit
import Alamofire import Alamofire
import SmartCodable import SmartCodable
enum YHAIResponseType: Int { class YHAIRequestManager: NSObject {
case none = 0
case text = 1
case card = 2
}
class YHAIMessage: CustomStringConvertible { static let shared = YHAIRequestManager()
static let sessionKey = "YINHE_SESSION_KEY"
var id: String = ""
var event: String = ""
var data: [String : Any] = [:]
var uuid: String = ""
var isSelf: Bool = false
var body = YHAIResponseBody()
func isFinishd() -> Bool {
if event.isEmpty {
return true
}
if event == "conversation.message.completed" {
return true
}
return false
}
func setFinished() { var sessionId: String = ""
event = "conversation.message.completed"
}
static func createQuestion(_ text: String) -> YHAIMessage { let prefix_id = "id:"
let question = YHAIMessage() let prefix_event = "event:"
question.isSelf = true let prefix_data = "data:"
let body = YHAIResponseBody() let viewModel = YHAIViewModel()
body.contentType = 1
body.contentText = text
question.setFinished()
question.body = body
return question
}
func getType() -> YHAIResponseType { var uuid = UUID().uuidString + NSDate().timeIntervalSince1970.description
if let type = data["contentType"] as? Int, type == 1 {
return .text
}
return .none
}
func getText() -> String { func getCommonHeaders() -> HTTPHeaders {
if getType() == .text {
if let text = data["contentText"] as? String, !text.isEmpty { var requestHeader = HTTPHeaders()
return text requestHeader.add(name: "Accept", value: "text/event-stream")
} requestHeader.add(name: "Connection", value: "keep-alive")
requestHeader.add(name:"appid",value:"1")
let dateStr = String(Date().timeIntervalSince1970)
requestHeader.add(name:"timestamp",value:dateStr)
requestHeader.add(name:"app_platform",value:"iOS")
requestHeader.add(name:"app_os",value:"iOS")
let version = UIDevice.appVersion()
requestHeader.add(name:"app_version",value:version)
requestHeader.add(name:"app_channel",value:"appStore")
requestHeader.add(name:"app_phoneModel",value:UIDevice.iPhoneModelName())
requestHeader.add(name:"os_version_name",value:UIDevice.iPhoneVersion())
requestHeader.add(name:"pass",value:"")
let appkey = "958364f87222c200a72414f492bf0e26"
let signOrgiString = "appid=" + "1" + "&" + "timestamp=" + dateStr + "&" + "appkey=" + appkey
let sign = signOrgiString.md5()
print("sign = \(sign)")
requestHeader.add(name:"sign",value:sign)
requestHeader.add(name: "token", value: YHLoginManager.shared.userModel?.token ?? "-")
if !YHLoginManager.shared.deviceTokenModel.registerId.isEmpty {
requestHeader.add(name: "device-id", value: YHLoginManager.shared.deviceTokenModel.registerId)
} }
return "" return requestHeader
} }
var description: String {
return "uudi:\(uuid)\n,id: \(id)\n, event: \(event)\n, data: \(data))\n\n"
}
}
class YHAIResponseBody: SmartCodable {
// "contentType":1,"contentText":"如何判断未来深圳的天气走势?","botId":"7439200648601714700","status":"completed"
var contentType: Int = 0
var contentText: String = ""
var botId: String = ""
var status: String = ""
required init() { func requestAI(botId: String, conversationId: String, question: String = "", completion: ((_: YHAIMessage) -> Void)?) {
self.getSessionId {
} sesseionId in
}
class YHAIRequestManager: NSObject { let url = YHBaseUrlManager.shared.curURL() + YHAllApiName.AIChat.agentChat
self.uuid = UUID().uuidString + NSDate().timeIntervalSince1970.description
static let shared = YHAIRequestManager() // body 请求体参数
let prefix_id = "id:" var parameters = ["botId" : botId,
let prefix_event = "event:" "conversationId" : conversationId,
let prefix_data = "data:" "question" : question]
var uuid = UUID().uuidString + NSDate().timeIntervalSince1970.description
parameters = ["botId": "7441190609433755702",
func requestAI(query: String = "", completion:((_ : YHAIMessage) ->())?) { "conversationId": sesseionId,
// var url = "http://192.168.52.250:9898/example "question": question] as! [String: String]
var url = YHBaseUrlManager.shared.curURL() + YHAllApiName.AIChat.agentChat + "?query=" + query
url = url.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)! let headers = self.getCommonHeaders()
self.uuid = UUID().uuidString + NSDate().timeIntervalSince1970.description // 发送 POST 请求
AF.streamRequest(url).responseStreamString { AF.streamRequest(url,
[weak self] stream in method: .post,
guard let self = self else { return } headers: headers,
switch stream.event { automaticallyCancelOnStreamError: false,
case let .stream(result): requestModifier: { request in
switch result { if let httpBodyStream = self.dictionaryToHttpBodyStream(parameters) {
case let .success(string): request.httpBodyStream = httpBodyStream
// print(string) }
self.handle(dataString: string) { }).responseStreamString {
[weak self] res in [weak self] stream in
// guard let self = self else { return } guard let self = self else { return }
completion?(res)
switch stream.event {
case let .stream(result):
switch result {
case let .success(string):
print(string)
self.handle(dataString: string) {
res in
completion?(res)
}
case let .failure(error):
print("\(error)")
}
case let .complete(completion):
if let af_error = completion.error {
if let error = af_error.underlyingError {
print("\(error)")
} else {
print("&&&&&&&&&&&&&&&&&&&&&&&&&&&&")
print("\(af_error)")
}
} else if let res = completion.response {
print("&&&&&&&&&&&&&&&&&&&&&&&&&&&&")
print("\(res)")
} else {
print("response done")
} }
case let .failure(error):
print("")
} }
case let .complete(completion):
print("response done")
} }
} }
} }
func dictionaryToHttpBodyStream(_ dic: [String: Any]) -> InputStream? {
do {
// 将字典序列化为 JSON 数据
let jsonData = try JSONSerialization.data(withJSONObject: dic, options: [])
// 创建一个 InputStream
let stream = InputStream(data: jsonData)
return stream
} catch {
print("Error serializing dictionary to JSON: \(error)")
return nil
}
}
// 处理data字符串 // 处理data字符串
func handle(dataString: String, completion:((_ : YHAIMessage) ->())?) { func handle(dataString: String, completion:((_ : YHAIMessage) ->())?) {
...@@ -182,3 +193,21 @@ class YHAIRequestManager: NSObject { ...@@ -182,3 +193,21 @@ class YHAIRequestManager: NSObject {
} }
} }
} }
extension YHAIRequestManager {
func getSessionId(completion:((String)->())?) {
if let sessionId = UserDefaults.standard.value(forKey: YHAIRequestManager.sessionKey) as? String, !sessionId.isEmpty {
completion?(sessionId)
} else {
self.viewModel.getConversationId { success, error in
let sessionId = self.viewModel.sessionId
UserDefaults.standard.set(sessionId, forKey: YHAIRequestManager.sessionKey)
UserDefaults.standard.synchronize()
completion?(self.viewModel.sessionId)
}
}
}
}
...@@ -83,7 +83,10 @@ class YHNetRequest: NSObject { ...@@ -83,7 +83,10 @@ class YHNetRequest: NSObject {
override init() { override init() {
super.init() super.init()
headers = YHNetRequest.getCommonHeaders()
}
static func getCommonHeaders() -> HTTPHeaders {
var requestHeader = HTTPHeaders() var requestHeader = HTTPHeaders()
requestHeader.add(name:"Conatent-Type",value:"application/json") requestHeader.add(name:"Conatent-Type",value:"application/json")
...@@ -114,7 +117,7 @@ class YHNetRequest: NSObject { ...@@ -114,7 +117,7 @@ class YHNetRequest: NSObject {
if !YHLoginManager.shared.deviceTokenModel.registerId.isEmpty { if !YHLoginManager.shared.deviceTokenModel.registerId.isEmpty {
requestHeader.add(name: "device-id", value: YHLoginManager.shared.deviceTokenModel.registerId) requestHeader.add(name: "device-id", value: YHLoginManager.shared.deviceTokenModel.registerId)
} }
headers = requestHeader return requestHeader
} }
func businessCode(_ code: String) -> Self { func businessCode(_ code: String) -> Self {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment