Commit 20a6f99a authored by Steven杜宇's avatar Steven杜宇

// AI

parent 4ad0a294
......@@ -669,6 +669,7 @@
04BD83452CCA2009003A88DF /* AlimamaShuHeiTi-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 04BD83442CCA2009003A88DF /* AlimamaShuHeiTi-Bold.ttf */; };
04BE39282CF848F300BD31DB /* YHAIMessageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04BE39272CF848F300BD31DB /* YHAIMessageModel.swift */; };
04BE392A2CF85F8900BD31DB /* YHAITabIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04BE39292CF85F8900BD31DB /* YHAITabIndicatorView.swift */; };
04BE392C2CF8917100BD31DB /* YHAIThinkingMessageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04BE392B2CF8917100BD31DB /* YHAIThinkingMessageCell.swift */; };
04C693622B723AB8004C1758 /* YHMySettingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04C693612B723AB8004C1758 /* YHMySettingViewController.swift */; };
04C693642B723B56004C1758 /* YHMySettingCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04C693632B723B56004C1758 /* YHMySettingCell.swift */; };
04C85DDF2C364FE9008B20D6 /* YHAboutUsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04C85DDE2C364FE9008B20D6 /* YHAboutUsCell.swift */; };
......@@ -1720,6 +1721,7 @@
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>"; };
04BE39292CF85F8900BD31DB /* YHAITabIndicatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHAITabIndicatorView.swift; sourceTree = "<group>"; };
04BE392B2CF8917100BD31DB /* YHAIThinkingMessageCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHAIThinkingMessageCell.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>"; };
04C85DDE2C364FE9008B20D6 /* YHAboutUsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHAboutUsCell.swift; sourceTree = "<group>"; };
......@@ -3966,6 +3968,7 @@
isa = PBXGroup;
children = (
04943BF32CF4954800BF2255 /* YHAIMessageCell.swift */,
04BE392B2CF8917100BD31DB /* YHAIThinkingMessageCell.swift */,
045F28452CF6C47800520F19 /* YHAIProductCell.swift */,
04943BF52CF49E3E00BF2255 /* YHAITextInputView.swift */,
045F28472CF6EF9800520F19 /* YHAIGreetCollectionReusableView.swift */,
......@@ -6071,6 +6074,7 @@
0472E25E2C534723008EAB6E /* YHLifeDetailViewController.swift in Sources */,
0457920D2CBCE8A800EBD99B /* YHResignUploadTravelCardListModel.swift in Sources */,
A5ACE92E2B4564F7002C94D2 /* YHValidateCodeInputView.swift in Sources */,
04BE392C2CF8917100BD31DB /* YHAIThinkingMessageCell.swift in Sources */,
045EEED82B9F171A0022A143 /* YHQuestionInfo.swift in Sources */,
A567E5B82BD7643D00D5D5A0 /* YHSearchItemLayout.swift in Sources */,
A567E5A02BD7643D00D5D5A0 /* YHHomeWebViewController.swift in Sources */,
......
......@@ -31,6 +31,7 @@ class YHAIChatViewController: YHBaseViewController {
tableView.dataSource = self
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "UITableViewCell")
tableView.register(YHAIMessageCell.self, forCellReuseIdentifier: YHAIMessageCell.cellReuseIdentifier)
tableView.register(YHAIThinkingMessageCell.self, forCellReuseIdentifier: YHAIThinkingMessageCell.cellReuseIdentifier)
return tableView
}()
......@@ -39,19 +40,25 @@ class YHAIChatViewController: YHBaseViewController {
v.sendBlock = {
[weak self] text in
guard let self = self else { return }
let question = YHAIMessage.createQuestion(text)
let question = YHAIMessage.createQuestionMessage(text)
messages.append(question)
messages.append(thinkingMessage)
self.scrollToBottom()
YHAIRequestManager.shared.requestAI(botId: "", conversationId: "", question:text) {
[weak self] res in
[weak self] res, done in
guard let self = self else { return }
self.handleMessage(res)
self.handleMessage(res, done)
}
}
return v
}()
lazy var thinkingMessage: YHAIMessage = {
let msg = YHAIMessage.createThinkingMesssage()
return msg
}()
override func viewDidLoad() {
super.viewDidLoad()
......@@ -74,19 +81,35 @@ class YHAIChatViewController: YHBaseViewController {
}
}
func handleMessage(_ res: YHAIMessage) {
var find = false
for msg in messages {
if msg.uuid == res.uuid {
find = true
if msg.getType() == .text {
msg.body.contentText += res.body.contentText
func handleMessage(_ res: YHAIMessage?, _ done: Bool) {
if let res = res {
var find = false
for msg in messages {
if msg.uuid == res.uuid {
find = true
if msg.getType() == .text {
msg.body.contentText += res.body.contentText
}
}
}
}
if !find {
messages.append(res)
if !find {
messages.append(res)
}
} else {
if done { // 思考完成
var findIndex = -1
for (index, msg) in messages.enumerated() {
if msg.getType() == .thinking {
findIndex = index
}
}
if findIndex != -1 {
messages.remove(at: findIndex)
}
self.tableView.reloadData()
}
}
self.scrollToBottom()
}
......@@ -112,10 +135,19 @@ extension YHAIChatViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if 0 <= indexPath.row, indexPath.row < messages.count {
let msg = messages[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: YHAIMessageCell.cellReuseIdentifier, for: indexPath) as! YHAIMessageCell
cell.message = msg
return cell
let msgType = msg.getType()
if msgType == .text {
let cell = tableView.dequeueReusableCell(withIdentifier: YHAIMessageCell.cellReuseIdentifier, for: indexPath) as! YHAIMessageCell
cell.message = msg
return cell
} else if msgType == .thinking {
let cell = tableView.dequeueReusableCell(withIdentifier: YHAIThinkingMessageCell.cellReuseIdentifier, for: indexPath) as! YHAIThinkingMessageCell
return cell
}
}
let defaultCell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell", for: indexPath)
......
......@@ -153,6 +153,7 @@ extension YHAIServiceListViewController: UICollectionViewDelegate, UICollectionV
if kind == UICollectionView.elementKindSectionHeader {
let headerView: YHAIGreetCollectionReusableView = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: YHAIGreetCollectionReusableView.reuseIdentifier, for: indexPath) as! YHAIGreetCollectionReusableView
headerView.updateGreetingText()
return headerView
}
return UICollectionReusableView()
......
......@@ -13,7 +13,8 @@ class YHAIMessageModel: NSObject {
}
enum YHAIResponseType: Int {
enum YHAIMessageType: Int {
case thinking = -1
case none = 0
case text = 1
case card = 2
......@@ -28,7 +29,7 @@ class YHAIMessage: CustomStringConvertible {
var uuid: String = ""
var isSelf: Bool = false
var body = YHAIResponseBody()
var body = YHAIMessageBody()
func isFinishd() -> Bool {
if event.isEmpty {
......@@ -44,10 +45,10 @@ class YHAIMessage: CustomStringConvertible {
event = "conversation.message.completed"
}
static func createQuestion(_ text: String) -> YHAIMessage {
static func createQuestionMessage(_ text: String) -> YHAIMessage {
let question = YHAIMessage()
question.isSelf = true
let body = YHAIResponseBody()
let body = YHAIMessageBody()
body.contentType = 1
body.contentText = text
question.setFinished()
......@@ -55,13 +56,30 @@ class YHAIMessage: CustomStringConvertible {
return question
}
func getType() -> YHAIResponseType {
if let type = data["contentType"] as? Int, type == 1 {
return .text
static func createThinkingMesssage() -> YHAIMessage {
let message = YHAIMessage()
message.isSelf = false
let body = YHAIMessageBody()
body.contentType = YHAIMessageType.thinking.rawValue
message.setFinished()
message.body = body
return message
}
// 获取消息类型
func getType() -> YHAIMessageType {
if self.body.contentType == YHAIMessageType.thinking.rawValue {
return .thinking
}
if let type = data["contentType"] as? Int {
if type == YHAIMessageType.text.rawValue {
return .text
}
}
return .none
}
// 获取文字消息的文字
func getText() -> String {
if getType() == .text {
if let text = data["contentText"] as? String, !text.isEmpty {
......@@ -76,8 +94,10 @@ class YHAIMessage: CustomStringConvertible {
}
}
class YHAIResponseBody: SmartCodable {
// "contentType":1,"contentText":"如何判断未来深圳的天气走势?","botId":"7439200648601714700","status":"completed"
class YHAIMessageBody: SmartCodable {
// eg {"contentType":1,"contentText":"如何判断未来深圳的天气走势?","botId":"7439200648601714700","status":"completed"}
var contentType: Int = 0
var contentText: String = ""
var botId: String = ""
......
......@@ -47,7 +47,12 @@ class YHAIGreetCollectionReusableView: UICollectionReusableView {
fatalError("init(coder:) has not been implemented")
}
func updateGreetingText() {
titleLabel.text = greetingBasedOnTime()
}
func createUI() {
self.addSubview(iconImgView)
self.addSubview(titleLabel)
self.addSubview(subtitleLabel)
......@@ -73,4 +78,37 @@ class YHAIGreetCollectionReusableView: UICollectionReusableView {
}
func greetingBasedOnTime() -> String {
let currentDate = Date()
let calendar = Calendar.current
let hour = calendar.component(.hour, from: currentDate)
let minute = calendar.component(.minute, from: currentDate)
var result = "Hi,"
switch (hour, minute) {
case (5..<8, _):
result += "早上好"
case (8, 0..<30):
result += "早上好"
case (8, 30..<60):
result += "上午好"
case (8..<11, _):
result += "上午好"
case (11..<14, _):
result += "中午好"
case (14..<18, _):
result += "下午好"
case (18..<24, _):
result += "晚上好"
case (0..<5, _):
result += "晚上好"
default:
result += "晚上好" // 默认情况
}
result += "!"
return result
}
}
//
// YHAIThinkingMessageCell.swift
// galaxy
//
// Created by Dufet on 2024/11/28.
// Copyright © 2024 https://www.galaxy-immi.com. All rights reserved.
//
import UIKit
class YHAIThinkingMessageCell: UITableViewCell {
static let cellReuseIdentifier = "YHAIThinkingMessageCell"
var whiteContentView: UIView = {
let v = UIView()
v.backgroundColor = .white
v.layer.cornerRadius = 4.0
v.clipsToBounds = true
return v
}()
lazy var messageLabel:UILabel = {
let lable = UILabel()
lable.textColor = UIColor.mainTextColor
lable.textAlignment = .left
lable.font = UIFont.PFSC_R(ofSize:14)
lable.text = "港小宝正在思考…"
return lable
}()
lazy var loadingImgView: UIImageView = {
let v = UIImageView(image: UIImage(named: "ai_chat_think_loading"))
return v
}()
required init?(coder: NSCoder) {
super.init(coder: coder)
}
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupUI()
}
func setupUI() {
selectionStyle = .none
contentView.backgroundColor = .clear
backgroundColor = .clear
contentView.addSubview(whiteContentView)
whiteContentView.addSubview(messageLabel)
whiteContentView.addSubview(loadingImgView)
whiteContentView.snp.makeConstraints { make in
make.left.equalTo(20)
make.right.lessThanOrEqualTo(-20)
make.top.equalTo(20)
make.bottom.equalTo(-20)
}
messageLabel.snp.makeConstraints { make in
make.left.equalTo(16)
make.right.equalTo(-16)
make.top.equalTo(16)
}
loadingImgView.snp.makeConstraints { make in
make.left.equalTo(messageLabel)
make.width.equalTo(26)
make.height.equalTo(18)
make.top.equalTo(messageLabel.snp.bottom).offset(6)
make.bottom.equalTo(-16)
}
}
}
......@@ -58,7 +58,7 @@ class YHAIRequestManager: NSObject {
}
func requestAI(botId: String, conversationId: String, question: String = "", completion: ((_: YHAIMessage) -> Void)?) {
func requestAI(botId: String, conversationId: String, question: String = "", completion: ((_ msg: YHAIMessage?, _ done: Bool) -> Void)?) {
self.getSessionId {
sesseionId in
......@@ -96,19 +96,22 @@ class YHAIRequestManager: NSObject {
print(string)
self.handle(dataString: string) {
res in
completion?(res)
completion?(res, false)
}
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)")
// completion?(nil, true)
}
} else if let res = completion.response {
print("&&&&&&&&&&&&&&&&&&&&&&&&&&&&")
print("\(res)")
......@@ -173,7 +176,7 @@ class YHAIRequestManager: NSObject {
let jsonDict = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any]
let dic = (jsonDict ?? [:])
response.data = dic
if let body = YHAIResponseBody.deserialize(from: dic) {
if let body = YHAIMessageBody.deserialize(from: dic) {
response.body = body
}
}
......
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Frame 2033196089.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Frame 2033196089-1.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
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