case commitFeedback(param:[String:Any])
/// 获取提交的帮助与反馈
case feedbackHistory
+ /// 根据产品名称获取产品信息
+ case productInfo(name:String)
/// 获取绑定的设备列表
case deviceList
/// 绑定设备
return "/uc/feedback"
case .feedbackHistory:
return "/uc/feedback"
-
+
+ case .productInfo(let name):
+ return "/dev/product-info/by-name"
case .deviceList:
return "/dev/device/list"
case .bindDevice(let param):
case let .commitFeedback(para):
params += para
break
+ case let .productInfo(name):
+ params["prodName"] = name
+ break
case let .bindDevice(para):
params += para
break
Logger.debug( "用户主动结束")
} else {
Logger.debug( "自动结束")
+ rhythView.stopTimer()
toolBar.recordBtn.isSelected = false
}
}
}
originalLabel.do { v in
v.text = "你好,欢迎使用AI翻译,点击下方按钮立即开始咱们的对话吧"
- v.font = .bold(14)
+ v.font = .medium(14)
v.textColor = .hexString("#606D80")
v.numberOfLines = 0
v.textAlignment = .left
v.image = UIImage(named: "chat_xiaoyin")
}
titleLabel.do {v in
-// v.text = "嗨!我是小音"
+ v.text = "嗨!我是小音"
v.numberOfLines = 0
v.textAlignment = .center
v.textColor = .hexString("#121212")
v.font = .bold(18)
}
desLabel.do {v in
-// v.text = "我可以帮你搜索、答疑、写作,请把你的任务交给 我吧~"
+ v.text = "我可以帮你搜索、答疑、写作,请把你的任务交给 我吧~"
v.numberOfLines = 0
v.textAlignment = .center
v.textColor = .hexString("#666666")
PcmSound.sharedInstance().delegate = self
JoyGemChatManager.shared().addObserver(self, forKeyPath: "isActive",options: [.new, .old], context: nil);
- let model = ChatCellModel()
- model.type = 0
- model.content = "我是你的新朋友,有什么我可以帮助到你的?"
- model.id = 0
- dataList.append(model)
+// let model = ChatCellModel()
+// model.type = 0
+// model.content = "我是你的新朋友,有什么我可以帮助到你的?"
+// model.id = 0
+// dataList.append(model)
loadRoleList()
}
JoyGemChatManager.shared().getSpeakerList {[weak self] speakers in
guard let self = self,speakers.count > 0 else{return}
self.roleList = speakers
- self.roleItem.role = speakers.first
- self.headerView.role = speakers.first
+ self.roleList.insert(xiaoYinRole(), at: 0)
+ self.roleItem.role = roleList.first
+ self.headerView.role = roleList.first
JoyGemChatManager.shared().setSpeaker(self.roleItem.role)
}
}
+ func xiaoYinRole()->JoyGemSpeaker{
+ let model = JoyGemSpeaker()
+ model.sid = "zh_female_tianmeitaozi_mars_bigtts"
+ model.name = "小音"
+ model.type = "default"
+ model.role = "test_xiaoyin"
+ return model
+ }
}
extension ChatVC:ChatRecordBarDelegate{
extension ChatVC : JoyGemChatManagerDelegate {
func chatManager(_ manager: JoyGemChatManager, audioData data: Data?, index: UInt, sampleRate: UInt, finish isFinish: Bool) {
-
+ if (!isTtsPlaying) {
+ isTtsPlaying = true
+ JoyGemChatManager.shared().playAudioStart()
+ }
+ PcmSound.sharedInstance().feed(data)
}
func chatManager(_ manager: JoyGemChatManager, stateChange code: JoyGemStateCode) {
}
func chatManager(_ manager: JoyGemChatManager, audioData data: Data?, finish isFinish: Bool) {
- if (!isTtsPlaying) {
- isTtsPlaying = true
- JoyGemChatManager.shared().playAudioStart()
- }
- PcmSound.sharedInstance().feed(data)
+
}
func chatManager(_ manager: JoyGemChatManager, requestText text: String?, index: UInt) {
//
import UIKit
import JoyGemAI
+
+
class NavigationBarItem: BaseView {
let icon = UIImageView()
let titleLabel = UILabel()
v.textColor = .rgb(0x121212)
v.font = .bold(14)
v.text = "智能体"
+ v.isHidden = true
}
}
let line = BrokenLineView()
let originalLabel = UILabel()
let translationLabel = UILabel()
- let copyIcon = UIImageView()
+ let playIcon = UIImageView()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
line.do { v in
// v.backgroundColor = .hexString("#93C6EC")
}
- copyIcon.do { v in
+ playIcon.do { v in
v.image = UIImage(named: "play_animate_3")
v.animationImages = [UIImage(named: "play_animate_1")!,UIImage(named: "play_animate_2")!,UIImage(named: "play_animate_3")!]
v.animationDuration = 0.6
v.animationRepeatCount = 0
- v.yc.addTap(target: self, action: #selector(copyAction))
+ v.yc.addTap(target: self, action: #selector(playAction))
+ v.isHidden = true
}
contentView.addSubview(bgView)
- bgView.addSubviews([originalLabel,translationLabel,line,copyIcon])
+ bgView.addSubviews([originalLabel,translationLabel,line,playIcon])
}
override func setupLayout() {
make.width.lessThanOrEqualTo(kScreenWid - 82)
make.bottom.equalToSuperview().inset(47)
}
- copyIcon.snp.makeConstraints { make in
+ playIcon.snp.makeConstraints { make in
make.right.equalToSuperview().inset(12)
make.size.equalTo(24)
make.bottom.equalToSuperview().inset(10)
translationLabel.text = data.response
}
}
- @objc func copyAction(){
+ @objc func playAction(){
// UIPasteboard.general.string = data.send + "\n" + data.response
// YLprogressHUD.showAutoHiden("已拷贝")
- if copyIcon.isAnimating {
- copyIcon.stopAnimating()
+ if playIcon.isAnimating {
+ playIcon.stopAnimating()
}
else{
- copyIcon.startAnimating()
+ playIcon.startAnimating()
}
}
}
let toolBar = RecordBar()
let tableView = UITableView(frame: CGRectZero, style: .plain)
let bg = UIImageView()
- var dataList:[(Chinese2EnglishCellModel,UInt)] = []
+ var dataList:[(Chinese2EnglishCellModel,Int)] = []
var pcmData = Data()
var recordFilePath : String?
+ var startIndex = 0//记录开始录音的次数,用于区分返回的数据
override func setupViews() {
navBar.title = "中英互译"
func recordBar(_ bar: RecordBar, stateChange state: RecordBarSate) {
if state == .start {
pcmData = Data()
- dataList.removeAll()
- refreshData()
-
+ startIndex += 100000
JoyGemSIDeviceManager.shared().originalLanguage = bar.leftItem.language.value
JoyGemSIDeviceManager.shared().targetLanguage = bar.rightItem.language.value
JoyGemSIDeviceManager.shared().start()
}
else if state == .stop{
JoyGemSIDeviceManager.shared().stop()
- bar.startAnimating {[weak self] in
- guard let self = self else{return}
- // toolBar.recordBtn.stopCli()
- guard let path = recordFilePath,let wavPath = DCFolder.recordFileResave(srcPath: path) else{return}
- let v = PopTextField()
- v.show()
- v.cancelTap = {
-
- }
- v.okTap = { [weak self] text in
- guard let self = self else{return}
- var origin = ""
- var translate = ""
- for (item,_) in dataList {
- origin += item.send + "\n"
- translate += item.response + "\n"
- }
-
-
- let model = RecordDetailModel()
- model.type = .translate
- model.from = bar.leftItem.language
- model.to = bar.rightItem.language
- model.name = text
- model.path = wavPath
- model.duration = YLToos.getDuration(model.path)
- model.origin = origin
- model.translate = translate
- App.shared.goToPage(RecordDetailVC(record: model))
- }
- }
}
}
}
func siDeviceManager(_ manager: JoyGemSIDeviceManager, didUpdateRaw model: JoyGemAsrModel) {
Logger.debug("text: \(model.text),index: \(model.index)")
let msg = dataList.firstIndex (where: { (str,idx) in
- return idx == model.index;
+ return idx == Int(model.index) + startIndex
})
if (msg == nil) {
- dataList.append((Chinese2EnglishCellModel(send: model.text),model.index))
+ dataList.append((Chinese2EnglishCellModel(send: model.text),Int(model.index) + startIndex))
} else {
let (item,_) = dataList[msg!]
item.send = model.text
func siDeviceManager(_ manager: JoyGemSIDeviceManager, didUpdateTranslate model: JoyGemAsrModel) {
let msg = dataList.firstIndex (where: { (str,idx) in
- return idx == model.index;
+ return idx == Int(model.index) + startIndex
})
if (msg == nil) {
- dataList.append((Chinese2EnglishCellModel(response: model.text),model.index))
+ dataList.append((Chinese2EnglishCellModel(response: model.text),Int(model.index) + startIndex))
} else {
let (item,_) = dataList[msg!]
item.response = model.text
class DialogSplitCell:BaseTableViewCell{
let bgView = UIView()
let originalLabel = UILabel()
- let copyIcon = UIImageView()
+ let playIcon = UIImageView()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
v.numberOfLines = 0
v.textAlignment = .left
}
- copyIcon.do { v in
+ playIcon.do { v in
v.image = UIImage(named: "play_animate_3")
v.animationImages = [UIImage(named: "play_animate_1")!,UIImage(named: "play_animate_2")!,UIImage(named: "play_animate_3")!]
v.animationDuration = 0.6
v.animationRepeatCount = 0
- v.yc.addTap(target: self, action: #selector(copyAction))
+ v.yc.addTap(target: self, action: #selector(playAction))
}
contentView.addSubview(bgView)
- bgView.addSubviews([originalLabel,copyIcon])
+ bgView.addSubviews([originalLabel,playIcon])
}
override func setupLayout() {
make.right.equalToSuperview().inset(50)
make.bottom.equalToSuperview().inset(14)
}
- copyIcon.snp.makeConstraints { make in
+ playIcon.snp.makeConstraints { make in
make.right.equalToSuperview().inset(12)
make.size.equalTo(24)
make.top.equalToSuperview().inset(12)
}
}
- @objc func copyAction(){
- // UIPasteboard.general.string = data.send + "\n" + data.response
- // YLprogressHUD.showAutoHiden("已拷贝")
- if copyIcon.isAnimating {
- copyIcon.stopAnimating()
+ @objc func playAction(){
+ if playIcon.isAnimating {
+ playIcon.stopAnimating()
}
else{
- copyIcon.startAnimating()
+ playIcon.startAnimating()
}
}
}
let line = BrokenLineView()
let originalLabel = UILabel()
let translationLabel = UILabel()
- let copyIcon = UIImageView()
+ let playIcon = UIImageView()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
line.do { v in
v.backgroundColor = .hexString("#93C6EC")
}
- copyIcon.do { v in
+ playIcon.do { v in
v.image = UIImage(named: "play_animate_3")
v.animationImages = [UIImage(named: "play_animate_1")!,UIImage(named: "play_animate_2")!,UIImage(named: "play_animate_3")!]
v.animationDuration = 0.6
v.animationRepeatCount = 0
- v.yc.addTap(target: self, action: #selector(copyAction))
+ v.yc.addTap(target: self, action: #selector(playAction))
+ v.isHidden = true
}
contentView.addSubview(bgView)
- bgView.addSubviews([originalLabel,translationLabel,line,copyIcon])
+ bgView.addSubviews([originalLabel,translationLabel,line,playIcon])
}
override func setupLayout() {
make.height.greaterThanOrEqualTo(15)
make.bottom.equalToSuperview().inset(14)
}
- copyIcon.snp.makeConstraints { make in
+ playIcon.snp.makeConstraints { make in
make.right.equalToSuperview().inset(12)
make.size.equalTo(24)
make.top.equalToSuperview().inset(12)
line.layoutIfNeeded()
}
}
- @objc func copyAction(){
+ @objc func playAction(){
// UIPasteboard.general.string = data.send + "\n" + data.response
// YLprogressHUD.showAutoHiden("已拷贝")
- if copyIcon.isAnimating {
- copyIcon.stopAnimating()
+ if playIcon.isAnimating {
+ playIcon.stopAnimating()
}
else{
- copyIcon.startAnimating()
+ playIcon.startAnimating()
}
}
}
BleManager.shared.stopScanDevice()
}
static func startConnecte(_ data:DCPeripheral){
- ConnectPopView.shared.stateDidChange(.connecting)
- BleManager.shared.connectPeripheral(data)
-
+ guard let name = data.device.name else {
+ return
+ }
+ getProductInfo(name: name) { model in
+ if let info = model{
+ ConnectPopView.shared.titleLabel.text = name
+ ConnectPopView.shared.imageView.kf.setImage(with: info.image.yc.asUrl)
+ ConnectPopView.shared.stateDidChange(.connecting)
+ }
+ else{
+ ConnectPopView.shared.titleLabel.text = name
+ ConnectPopView.shared.stateDidChange(.connecting)
+ }
+ BleManager.shared.connectPeripheral(data)
+
+ }
}
/// 带冒号
static func getDeviceInfo(_ device:DCPeripheral){
}
return result
}
+
+ static func getProductInfo(name:String,finished:@escaping ((_ model:ProductInfoModel?)->Void)){
+ let api = CommomApi.productInfo(name: name)
+ HttpClient.request(api) {(model:ProductInfoModelRoot,res) in
+ if model.isSuccess{
+ finished(model.data)
+ }
+ else{
+ finished(nil)
+ }
+ }
+ }
}
extension DeviceVM{
--- /dev/null
+//
+// Untitled.swift
+// ShenYin
+//
+// Created by liangshi on 2025/11/5.
+//
+
+import HandyJSON
+
+class ProductInfoModelRoot:ResponseBaseModel {
+ var data = ProductInfoModel()
+}
+class ProductInfoModel:HandyJSON {
+ var id = ""
+ var name = ""
+ var image = ""
+ var description = ""
+ required public init() { }
+}
+
//MARK: 初始化SDK
JoyGemAIManager.shared().initSdk()
//MARK: 配置日志类型
- JoyGemAIManager.shared().setLogMode(JoyGemLogMode.all)
-
+// JoyGemAIManager.shared().setLogMode(JoyGemLogMode.all)
+ JoyGemAIManager.shared().setLogMode(JoyGemLogMode.close)
let fileManager = FileManager.default
if let appSupportDirectory = fileManager.urls(for: .applicationSupportDirectory, in: .userDomainMask).first {
m.top.equalToSuperview().inset(60)
m.left.equalToSuperview().inset(38)
m.height.equalTo(30)
- m.width.equalTo(120)
+ m.width.equalTo(130)
}
icon.snp.makeConstraints { (m) in
m.size.equalTo(80)
class ConnectPopView: BasePresentView2 {
static let shared = ConnectPopView()
let contentView = UIView()
- private let titleLabel = UILabel()
- private let imageView = UIImageView()
+ let titleLabel = UILabel()
+ let imageView = UIImageView()
private let desLabel = UILabel()