Commit 6142a608 authored by Steven杜宇's avatar Steven杜宇

// AI

parent 6db9155b
......@@ -670,6 +670,8 @@
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 */; };
04BE392E2CF964A200BD31DB /* YHProductListMessageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04BE392D2CF964A200BD31DB /* YHProductListMessageCell.swift */; };
04BE39302CF964F800BD31DB /* YHProductItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04BE392F2CF964F800BD31DB /* YHProductItemView.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 */; };
......@@ -1722,6 +1724,8 @@
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>"; };
04BE392D2CF964A200BD31DB /* YHProductListMessageCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHProductListMessageCell.swift; sourceTree = "<group>"; };
04BE392F2CF964F800BD31DB /* YHProductItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHProductItemView.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>"; };
......@@ -3973,6 +3977,8 @@
04943BF52CF49E3E00BF2255 /* YHAITextInputView.swift */,
045F28472CF6EF9800520F19 /* YHAIGreetCollectionReusableView.swift */,
04BE39292CF85F8900BD31DB /* YHAITabIndicatorView.swift */,
04BE392D2CF964A200BD31DB /* YHProductListMessageCell.swift */,
04BE392F2CF964F800BD31DB /* YHProductItemView.swift */,
);
path = V;
sourceTree = "<group>";
......@@ -3983,6 +3989,7 @@
045F28412CF6028A00520F19 /* YHAITabViewController.swift */,
04943BE92CF1B44100BF2255 /* YHAIChatViewController.swift */,
045F28432CF608C100520F19 /* YHAIServiceListViewController.swift */,
04943BEC2CF46B6600BF2255 /* YHAIRequestManager.swift */,
);
path = C;
sourceTree = "<group>";
......@@ -5114,7 +5121,6 @@
A5ACE8F42B4564F7002C94D2 /* YHNetRequest.swift */,
A5ACE8F52B4564F7002C94D2 /* YHNetworkStatusManager.swift */,
A5ACE8F62B4564F7002C94D2 /* YHBaseUrlManager.swift */,
04943BEC2CF46B6600BF2255 /* YHAIRequestManager.swift */,
);
path = NetWork;
sourceTree = "<group>";
......@@ -6298,6 +6304,7 @@
045EEEC12B9F171A0022A143 /* YHOtherInfoFillModel.swift in Sources */,
047A3DF52C295AFF0048937B /* YHFriendListModel.swift in Sources */,
04912F722CB7714300CC3105 /* YHResignAppointTimeSingleCell.swift in Sources */,
04BE39302CF964F800BD31DB /* YHProductItemView.swift in Sources */,
0468D43A2B579EAC00CFB916 /* YHLoginViewModel.swift in Sources */,
04CE1AD72C2AD91F001CB80A /* YHActivityDetailViewController.swift in Sources */,
045EEE9E2B9F171A0022A143 /* YHWorkExampleModel.swift in Sources */,
......@@ -6355,6 +6362,7 @@
045EEF0F2B9F171A0022A143 /* YHSelectCountryViewModel.swift in Sources */,
04F2432B2C942B5100DF2C74 /* YHResignDocumentTipsCell.swift in Sources */,
A567E59F2BD7643D00D5D5A0 /* YHStartPageViewController.swift in Sources */,
04BE392E2CF964A200BD31DB /* YHProductListMessageCell.swift in Sources */,
045EEF202B9F171A0022A143 /* YHCardExampleView.swift in Sources */,
A567E5A72BD7643D00D5D5A0 /* YHHomeKingKongBlockView.swift in Sources */,
04912F8C2CB907F200CC3105 /* YHResignAppointTimeMultipleCell.swift in Sources */,
......
......@@ -32,6 +32,8 @@ class YHAIChatViewController: YHBaseViewController {
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "UITableViewCell")
tableView.register(YHAIMessageCell.self, forCellReuseIdentifier: YHAIMessageCell.cellReuseIdentifier)
tableView.register(YHAIThinkingMessageCell.self, forCellReuseIdentifier: YHAIThinkingMessageCell.cellReuseIdentifier)
tableView.register(YHProductListMessageCell.self, forCellReuseIdentifier: YHProductListMessageCell.cellReuseIdentifier)
return tableView
}()
......@@ -40,6 +42,8 @@ class YHAIChatViewController: YHBaseViewController {
v.sendBlock = {
[weak self] text in
guard let self = self else { return }
self.removeThinkingMessage()
let question = YHAIMessage.createQuestionMessage(text)
messages.append(question)
messages.append(thinkingMessage)
......@@ -89,8 +93,10 @@ class YHAIChatViewController: YHBaseViewController {
var find = false
for msg in messages {
if msg.uuid == res.uuid {
find = true
if msg.getType() == .text {
let msgType = msg.getType()
if msgType == .text, res.getType() == .text {
// 多个文字需要拼接
find = true
msg.body.contentText += res.body.contentText
}
}
......@@ -152,6 +158,13 @@ extension YHAIChatViewController: UITableViewDelegate, UITableViewDataSource {
} else if msgType == .thinking {
let cell = tableView.dequeueReusableCell(withIdentifier: YHAIThinkingMessageCell.cellReuseIdentifier, for: indexPath) as! YHAIThinkingMessageCell
return cell
} else if msgType == .productList {
let cell = tableView.dequeueReusableCell(withIdentifier: YHProductListMessageCell.cellReuseIdentifier, for: indexPath) as! YHProductListMessageCell
if let listModel = msg.body.getProductList() {
cell.listModel = listModel
}
return cell
}
}
......@@ -162,10 +175,7 @@ extension YHAIChatViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 1.0
......
......@@ -152,19 +152,19 @@ class YHAIRequestManager: NSObject {
}
let lines = text.components(separatedBy: "\n")
if lines.count > 0 {
let response = YHAIMessage()
response.uuid = uuid
let receiveMessage = YHAIMessage()
receiveMessage.uuid = uuid
for line in lines {
if line.starts(with: prefix_id) {
if let idRange = line.range(of: prefix_id) {
let id = String(line[idRange.upperBound...])
response.id = id
receiveMessage.id = id
}
} else if line.starts(with: prefix_event) {
if let eventRange = line.range(of: prefix_event) {
let eventString = String(line[eventRange.upperBound...])
response.event = eventString
receiveMessage.event = eventString
}
} else if line.starts(with: prefix_data) {
......@@ -175,9 +175,9 @@ class YHAIRequestManager: NSObject {
if let jsonData = jsonString.data(using: .utf8) {
let jsonDict = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any]
let dic = (jsonDict ?? [:])
response.data = dic
receiveMessage.data = dic
if let body = YHAIMessageBody.deserialize(from: dic) {
response.body = body
receiveMessage.body = body
}
}
......@@ -187,11 +187,12 @@ class YHAIRequestManager: NSObject {
}
}
}
if response.isFinishd() {
if receiveMessage.isFinishd() {
// 一段话结束需要重新生成uuid 来
uuid = UUID().uuidString + NSDate().timeIntervalSince1970.description
}
completion?(response)
print("msgType: \(receiveMessage.getType()), compltete:\(receiveMessage.isFinishd()), uuid:\(receiveMessage.uuid), \(receiveMessage.body.contentText)")
completion?(receiveMessage)
}
}
}
......
......@@ -18,6 +18,7 @@ enum YHAIMessageType: Int {
case none = 0
case text = 1
case card = 2
case productList = 3
}
class YHAIMessage: CustomStringConvertible {
......@@ -82,6 +83,9 @@ class YHAIMessage: CustomStringConvertible {
if type == YHAIMessageType.text.rawValue {
return .text
}
if type == YHAIMessageType.productList.rawValue {
return .productList
}
}
return .none
}
......@@ -103,12 +107,72 @@ class YHAIMessage: CustomStringConvertible {
class YHAIMessageBody: SmartCodable {
// eg {"contentType":1,"contentText":"如何判断未来深圳的天气走势?","botId":"7439200648601714700","status":"completed"}
// {"contentType":1, "contentText":"11月爆款楼盘。", "botId":"7441190609433755702", "status":"delta", "type":"answer", "chatId":"7442585762052194356"
var contentType: Int = 0
var contentText: String = ""
var botId: String = ""
var status: String = ""
var type: String = ""
var productListModel: YHProductListModel = YHProductListModel()
func getProductList() -> YHProductListModel? {
do {
if let jsonData = contentText.data(using: .utf8) {
let dataDict = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any]
let dict = dataDict ?? [:]
if contentType == YHAIMessageType.productList.rawValue {
if let productList = YHProductListModel.deserialize(from: dict) {
return productList
}
}
}
} catch {
}
return nil
}
required init() {
}
}
class YHProductListModel: SmartCodable {
var icon: String = ""
var title: String = ""
var description: String = ""
var btnText: String = ""
var redirectMode: Int = 0
var redirectPath: String = ""
var list: [YHProductItemModel] = []
required init() {
}
}
class YHProductItemModel: SmartCodable {
var title: String = ""
var cover: String = ""
var redirectMode: Int = 0
var redirectPath: String = ""
var tags: [YHProductTag] = []
var originalPrice: Int = 0
var discountPrice: Int = 0
required init() {
}
}
class YHProductTag: SmartCodable {
var text: String = ""
var color: String = ""
required init() {
......
//
// YHProductItemView.swift
// galaxy
//
// Created by Dufet on 2024/11/29.
// Copyright © 2024 https://www.galaxy-immi.com. All rights reserved.
//
import UIKit
import AttributedString
class YHProductItemView: UIView {
var productModel = YHProductItemModel() {
didSet {
iconImgView.sd_setImage(with: URL(string: productModel.cover), placeholderImage: UIImage(named: "global_default_image"))
titleLabel.text = productModel.title
let aa: ASAttributedString = .init("¥", .font(UIFont(name: "DINAlternate-Bold", size: 14)!),.foreground(UIColor.mainTextColor))
let bb: ASAttributedString = .init("\(productModel.discountPrice)", .font(UIFont(name: "DINAlternate-Bold", size: 20)!),.foreground(UIColor.mainTextColor))
let cc: ASAttributedString = .init("¥\(productModel.originalPrice)", .font(UIFont(name: "DINAlternate-Bold", size: 14)!),.foreground(UIColor.init(hex: 0xB9C1CC)), .strikethrough(.single))
priceLabel.attributed.text = aa+bb+cc
tagContentView.removeSubviews()
var lastTagView:YHProductTagView? = nil
for tagModel in productModel.tags {
let v = YHProductTagView()
v.tagModel = tagModel
tagContentView.addSubview(v)
v.snp.makeConstraints { make in
make.top.bottom.equalTo(0)
if let lastTagView = lastTagView {
make.left.equalTo(lastTagView.snp.right).offset(4)
} else {
make.left.equalTo(0)
}
}
lastTagView = v
}
self.setNeedsLayout()
self.layoutIfNeeded()
}
}
lazy var bottomLineView: UIView = {
let v = UIView()
v.backgroundColor = .init(hex: 0xE9ECF0)
return v
}()
lazy var iconImgView: UIImageView = {
let v = UIImageView(image: UIImage(named: ""))
return v
}()
lazy var titleLabel:UILabel = {
let lable = UILabel()
lable.textColor = UIColor.mainTextColor
lable.textAlignment = .left
lable.font = UIFont.PFSC_R(ofSize:14)
lable.text = "高才A香港企明星(7)"
return lable
}()
lazy var tagContentView: UIView = {
let v = UIView()
return v
}()
lazy var priceLabel:UILabel = {
let label = UILabel()
label.numberOfLines = 0
let aa: ASAttributedString = .init("¥", .font(UIFont(name: "DINAlternate-Bold", size: 14)!),.foreground(UIColor.mainTextColor))
let bb: ASAttributedString = .init("61000", .font(UIFont(name: "DINAlternate-Bold", size: 20)!),.foreground(UIColor.mainTextColor))
let cc: ASAttributedString = .init("¥61000", .font(UIFont(name: "DINAlternate-Bold", size: 14)!),.foreground(UIColor.mainTextColor), .strikethrough(.single))
label.attributed.text = aa+bb+cc
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
createUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc func didClickProductItem() {
if !productModel.redirectPath.isEmpty {
let vc = YHH5WebViewVC()
vc.isFullScreenFlag = false
vc.url = productModel.redirectPath
UIViewController.current?.navigationController?.pushViewController(vc)
}
}
func createUI() {
let tap = UITapGestureRecognizer(target: self, action: #selector(didClickProductItem))
self.addGestureRecognizer(tap)
self.addSubview(iconImgView)
self.addSubview(titleLabel)
self.addSubview(tagContentView)
self.addSubview(priceLabel)
self.addSubview(bottomLineView)
iconImgView.snp.makeConstraints { make in
make.width.height.equalTo(80)
make.left.equalTo(16)
make.top.equalTo(20)
make.bottom.equalTo(-20)
}
titleLabel.snp.makeConstraints { make in
make.left.equalTo(iconImgView.snp.right).offset(12)
make.right.equalTo(-12)
make.top.equalTo(iconImgView)
make.height.equalTo(22)
}
tagContentView.snp.makeConstraints { make in
make.left.equalTo(titleLabel)
make.right.equalTo(-12)
make.height.equalTo(16)
make.top.equalTo(titleLabel.snp.bottom).offset(4)
}
priceLabel.snp.makeConstraints { make in
make.left.equalTo(titleLabel)
make.right.equalTo(-12)
make.bottom.equalTo(iconImgView)
make.height.equalTo(20)
}
bottomLineView.snp.makeConstraints { make in
make.left.equalTo(iconImgView)
make.right.equalTo(-12)
make.height.equalTo(0.5)
make.bottom.equalTo(0)
}
}
}
class YHProductTagView: UIView {
var tagModel: YHProductTag = YHProductTag() {
didSet {
tagLabel.text = tagModel.text
self.setNeedsLayout()
self.layoutIfNeeded()
}
}
lazy var tagLabel:UILabel = {
let lable = UILabel()
lable.textColor = UIColor.mainTextColor
lable.textAlignment = .center
lable.font = UIFont.PFSC_R(ofSize:10)
lable.text = "新品"
return lable
}()
override init(frame: CGRect) {
super.init(frame: frame)
createUI()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
func createUI() {
self.layer.borderColor = UIColor.mainTextColor.cgColor
self.layer.borderWidth = 0.5
self.clipsToBounds = true
self.addSubview(tagLabel)
tagLabel.snp.makeConstraints { make in
make.top.bottom.equalToSuperview()
make.left.equalTo(5)
make.right.equalTo(-5)
}
}
}
//
// YHProductListMessageCell.swift
// galaxy
//
// Created by Dufet on 2024/11/29.
// Copyright © 2024 https://www.galaxy-immi.com. All rights reserved.
//
import UIKit
class YHProductListMessageCell: UITableViewCell {
static let cellReuseIdentifier = "YHProductListMessageCell"
var listModel = YHProductListModel() {
didSet {
iconImgView.sd_setImage(with: URL(string: listModel.icon))
titleLabel.text = listModel.title
subtitleLabel.text = listModel.description
listView.removeSubviews()
var lastItemView:YHProductItemView? = nil
for (index, item) in listModel.list.enumerated() {
let productView = YHProductItemView()
productView.productModel = item
listView.addSubview(productView)
productView.snp.makeConstraints { make in
make.left.right.equalToSuperview()
if let lastItemView = lastItemView {
make.top.equalTo(lastItemView.snp.bottom)
} else {
make.top.equalTo(0)
}
if index == listModel.list.count-1 {
make.bottom.equalTo(0)
}
}
lastItemView = productView
}
self.setNeedsLayout()
self.layoutIfNeeded()
}
}
var whiteContentView: UIView = {
let v = UIView()
v.backgroundColor = .white
v.layer.cornerRadius = 4.0
v.clipsToBounds = true
return v
}()
lazy var iconImgView: UIImageView = {
let v = UIImageView(image: UIImage(named: ""))
return v
}()
lazy var titleLabel:UILabel = {
let lable = UILabel()
lable.textColor = UIColor.mainTextColor
lable.textAlignment = .left
lable.font = UIFont.PFSC_B(ofSize:16)
lable.text = "港小宝"
return lable
}()
lazy var subtitleLabel:UILabel = {
let lable = UILabel()
lable.textColor = UIColor.init(hex: 0x8993A2)
lable.textAlignment = .left
lable.font = UIFont.PFSC_R(ofSize:12)
lable.text = "为您推荐以下优才产品"
return lable
}()
lazy var lineView: UIView = {
let v = UIView()
v.backgroundColor = .init(hex: 0xE9ECF0)
return v
}()
lazy var listView: UIView = {
let v = UIView()
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(iconImgView)
whiteContentView.addSubview(titleLabel)
whiteContentView.addSubview(subtitleLabel)
whiteContentView.addSubview(lineView)
whiteContentView.addSubview(listView)
whiteContentView.snp.makeConstraints { make in
make.left.equalTo(20)
make.right.equalTo(-20)
make.top.equalTo(16)
make.bottom.equalTo(-16)
}
iconImgView.snp.makeConstraints { make in
make.width.height.equalTo(36)
make.top.equalTo(20)
make.left.equalTo(16)
}
titleLabel.snp.makeConstraints { make in
make.top.equalTo(iconImgView)
make.left.equalTo(iconImgView.snp.right).offset(8)
make.height.equalTo(24)
make.right.equalTo(-16)
}
subtitleLabel.snp.makeConstraints { make in
make.left.equalTo(titleLabel)
make.top.equalTo(titleLabel.snp.bottom).offset(0)
make.height.equalTo(20)
make.right.equalTo(-16)
}
lineView.snp.makeConstraints { make in
make.left.equalTo(16)
make.right.equalTo(-16)
make.top.equalTo(subtitleLabel.snp.bottom).offset(10)
make.height.equalTo(0.5)
}
listView.snp.makeConstraints { make in
make.left.equalTo(16)
make.right.equalTo(-16)
make.top.equalTo(lineView.snp.bottom).offset(0)
make.bottom.equalTo(0)
}
}
}
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