Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Q
qk_backend
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
quanku
qk_backend
Commits
68e5444b
Commit
68e5444b
authored
Oct 18, 2023
by
shiyu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
IM
parent
93d6514f
Changes
29
Show whitespace changes
Inline
Side-by-side
Showing
29 changed files
with
1169 additions
and
21 deletions
+1169
-21
ch-core/src/main/java/com/wwdz/ch/core/consts/IMEnum.java
ch-core/src/main/java/com/wwdz/ch/core/consts/IMEnum.java
+84
-0
ch-core/src/main/java/com/wwdz/ch/core/entity/im/IMChatMsg.java
...e/src/main/java/com/wwdz/ch/core/entity/im/IMChatMsg.java
+64
-0
ch-core/src/main/java/com/wwdz/ch/core/entity/im/IMChatRequestDto.java
...ain/java/com/wwdz/ch/core/entity/im/IMChatRequestDto.java
+37
-0
ch-core/src/main/java/com/wwdz/ch/core/entity/im/IMHistoryMsgRequestDto.java
...va/com/wwdz/ch/core/entity/im/IMHistoryMsgRequestDto.java
+43
-0
ch-core/src/main/java/com/wwdz/ch/core/entity/im/IMUser.java
ch-core/src/main/java/com/wwdz/ch/core/entity/im/IMUser.java
+23
-0
ch-core/src/main/java/com/wwdz/ch/core/entity/im/SendChatMsgRequestDto.java
...ava/com/wwdz/ch/core/entity/im/SendChatMsgRequestDto.java
+57
-0
ch-core/src/main/java/com/wwdz/ch/core/entity/im/vo/IMChatVo.java
...src/main/java/com/wwdz/ch/core/entity/im/vo/IMChatVo.java
+8
-0
ch-core/src/main/java/com/wwdz/ch/core/im/Base64URL.java
ch-core/src/main/java/com/wwdz/ch/core/im/Base64URL.java
+1
-1
ch-core/src/main/java/com/wwdz/ch/core/im/TLSSigAPIv2.java
ch-core/src/main/java/com/wwdz/ch/core/im/TLSSigAPIv2.java
+8
-7
ch-core/src/main/java/com/wwdz/ch/core/im/api/ChatUserApi.java
...re/src/main/java/com/wwdz/ch/core/im/api/ChatUserApi.java
+100
-0
ch-core/src/main/java/com/wwdz/ch/core/im/api/ConversationApi.java
...rc/main/java/com/wwdz/ch/core/im/api/ConversationApi.java
+127
-0
ch-core/src/main/java/com/wwdz/ch/core/im/api/TLSSigApi.java
ch-core/src/main/java/com/wwdz/ch/core/im/api/TLSSigApi.java
+85
-0
ch-core/src/main/java/com/wwdz/ch/core/util/IMUtil.java
ch-core/src/main/java/com/wwdz/ch/core/util/IMUtil.java
+57
-0
ch-core/src/main/resources/application-dev.yml
ch-core/src/main/resources/application-dev.yml
+8
-1
ch-core/src/main/resources/application-prod.yml
ch-core/src/main/resources/application-prod.yml
+7
-0
ch-dao/src/main/java/com/wwdz/ch/db/dao/AiAssistantDao.java
ch-dao/src/main/java/com/wwdz/ch/db/dao/AiAssistantDao.java
+2
-0
ch-dao/src/main/java/com/wwdz/ch/db/dao/UserDao.java
ch-dao/src/main/java/com/wwdz/ch/db/dao/UserDao.java
+5
-0
ch-dao/src/main/java/com/wwdz/ch/db/domain/AiAssistant.java
ch-dao/src/main/java/com/wwdz/ch/db/domain/AiAssistant.java
+11
-1
ch-dao/src/main/java/com/wwdz/ch/db/domain/AiAssistantExample.java
...c/main/java/com/wwdz/ch/db/domain/AiAssistantExample.java
+142
-0
ch-dao/src/main/java/com/wwdz/ch/db/dto/request/AiAssistantRequestDto.java
...ava/com/wwdz/ch/db/dto/request/AiAssistantRequestDto.java
+5
-0
ch-dao/src/main/java/com/wwdz/ch/db/impl/AiAssistantDaoImpl.java
...src/main/java/com/wwdz/ch/db/impl/AiAssistantDaoImpl.java
+7
-0
ch-dao/src/main/java/com/wwdz/ch/db/impl/UserDaoImpl.java
ch-dao/src/main/java/com/wwdz/ch/db/impl/UserDaoImpl.java
+8
-0
ch-dao/src/main/resources/com/wwdz/ch/db/mapper/AiAssistantMapper.xml
...ain/resources/com/wwdz/ch/db/mapper/AiAssistantMapper.xml
+27
-9
ch-wx-api/src/main/java/com/wwdz/ch/wx/config/WebMvcConfiguration.java
.../main/java/com/wwdz/ch/wx/config/WebMvcConfiguration.java
+2
-1
ch-wx-api/src/main/java/com/wwdz/ch/wx/impl/IMServiceImpl.java
...-api/src/main/java/com/wwdz/ch/wx/impl/IMServiceImpl.java
+84
-0
ch-wx-api/src/main/java/com/wwdz/ch/wx/service/IMService.java
...x-api/src/main/java/com/wwdz/ch/wx/service/IMService.java
+30
-0
ch-wx-api/src/main/java/com/wwdz/ch/wx/web/AiAssistantController.java
...c/main/java/com/wwdz/ch/wx/web/AiAssistantController.java
+2
-0
ch-wx-api/src/main/java/com/wwdz/ch/wx/web/IMController.java
ch-wx-api/src/main/java/com/wwdz/ch/wx/web/IMController.java
+68
-0
ch-wx-api/src/test/java/com/wwdz/ch/wx/api/ChatApiTest.java
ch-wx-api/src/test/java/com/wwdz/ch/wx/api/ChatApiTest.java
+67
-1
No files found.
ch-core/src/main/java/com/wwdz/ch/core/consts/IMEnum.java
0 → 100644
View file @
68e5444b
package
com.wwdz.ch.core.consts
;
/**
* IM对话枚举
*/
public
class
IMEnum
{
public
enum
MsgTypeEnum
{
TIMTextElem
(
1
,
"文本消息"
,
"TIMTextElem"
),
TIMLocationElem
(
2
,
"位置消息"
,
"TIMLocationElem"
),
TIMFaceElem
(
3
,
"表情消息"
,
"TIMFaceElem"
),
TIMCustomElem
(
4
,
"自定义消息"
,
"TIMCustomElem"
),
TIMSoundElem
(
5
,
"语音消息"
,
"TIMSoundElem"
),
TIMImageElem
(
6
,
"图像消息"
,
"TIMImageElem"
),
TIMFileElem
(
7
,
"文件消息"
,
"TIMFileElem"
),
TIMVideoFileElem
(
8
,
"视频消息"
,
"TIMVideoFileElem"
),
;
private
int
code
;
private
String
des
;
private
String
value
;
MsgTypeEnum
(
int
code
,
String
des
,
String
value
)
{
this
.
code
=
code
;
this
.
des
=
des
;
this
.
value
=
value
;
}
public
static
String
getValueByCode
(
int
code
)
{
for
(
IMEnum
.
MsgTypeEnum
msgTypeEnum
:
IMEnum
.
MsgTypeEnum
.
values
())
{
if
(
code
==
msgTypeEnum
.
getCode
())
{
return
msgTypeEnum
.
getValue
();
}
}
return
null
;
}
public
int
getCode
()
{
return
code
;
}
public
String
getDes
()
{
return
des
;
}
public
String
getValue
()
{
return
value
;
}
}
public
enum
SyncOtherMachineEnum
{
SYNC
(
1
,
"消息同步至发送方"
),
NOT_SYNC
(
2
,
"消息不S同步至发送方"
),
;
private
int
code
;
private
String
des
;
SyncOtherMachineEnum
(
int
code
,
String
des
)
{
this
.
code
=
code
;
this
.
des
=
des
;
}
public
static
String
getNameByCode
(
int
code
)
{
for
(
IMEnum
.
SyncOtherMachineEnum
syncOtherMachineEnum
:
IMEnum
.
SyncOtherMachineEnum
.
values
())
{
if
(
code
==
syncOtherMachineEnum
.
getCode
())
{
return
syncOtherMachineEnum
.
getDes
();
}
}
return
null
;
}
public
int
getCode
()
{
return
code
;
}
public
String
getDes
()
{
return
des
;
}
}
}
ch-core/src/main/java/com/wwdz/ch/core/entity/im/IMChatMsg.java
0 → 100644
View file @
68e5444b
package
com.wwdz.ch.core.entity.im
;
import
com.wwdz.ch.core.consts.IMEnum
;
import
com.xxdxxs.entity.Entity
;
import
lombok.Data
;
import
java.lang.reflect.Array
;
import
java.util.Arrays
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
@Data
public
class
IMChatMsg
implements
Entity
{
/**
* 1:把消息同步到 From_Account 在线终端和漫游上
* 2:消息不同步至 From_Account
* 若不填写默认情况下会将消息存 From_Account 漫游
*/
private
Integer
SyncOtherMachine
;
/**
* 消息发送方 UserID(用于指定发送消息方账号)
*/
private
String
From_Account
;
/**
* 消息接收方 UserID
*/
private
String
To_Account
;
/**
* 消息离线保存时长(单位:秒),最长为7天(604800秒)
* 若设置该字段为0,则消息只发在线用户,不保存离线
* 若设置该字段超过7天(604800秒),仍只保存7天
* 若不设置该字段,则默认保存7天
*/
private
Integer
MsgLifeTime
;
/**
* 消息序列号(32位无符号整数),后台会根据该字段去重及进行同秒内消息的排序,
* 详细规则请看本接口的功能说明。若不填该字段,则由后台填入随机数
*/
private
Integer
MsgSeq
;
/**
* 消息随机数(32位无符号整数),后台用于同一秒内的消息去重。请确保该字段填的是随机
*/
private
Integer
MsgRandom
;
/**
* 消息主体
* 其中包含
* MsgType 消息类型
* MsgContent 消息内容
*/
private
List
MsgBody
;
}
ch-core/src/main/java/com/wwdz/ch/core/entity/im/IMChatRequestDto.java
0 → 100644
View file @
68e5444b
package
com.wwdz.ch.core.entity.im
;
import
com.wwdz.ch.db.dto.request.BaseRequestDto
;
import
com.xxdxxs.entity.Entity
;
import
lombok.Data
;
@Data
public
class
IMChatRequestDto
extends
BaseRequestDto
implements
Entity
{
private
Long
userId
;
/**
* 普通会话的起始时间,第一页填 0。
*/
private
Integer
timeStamp
;
/**
* 普通会话的起始位置,第一页填 0。
*/
private
Integer
startIndex
;
/**
* 置顶会话的起始时间,第一页填 0。
*/
private
Integer
topTimeStamp
;
/**
* 置顶会话的起始位置,第一页填 0。
*/
private
Integer
topStartIndex
;
}
ch-core/src/main/java/com/wwdz/ch/core/entity/im/IMHistoryMsgRequestDto.java
0 → 100644
View file @
68e5444b
package
com.wwdz.ch.core.entity.im
;
import
com.xxdxxs.entity.Entity
;
import
lombok.Data
;
/**
* 历史聊天记录请求参数类
*/
@Data
public
class
IMHistoryMsgRequestDto
implements
Entity
{
/**
* 历史聊天记录查询的发起方
*/
private
String
operatorAccount
;
/**
* 会话的另一方
*/
private
String
peerAccount
;
/**
* 请求的消息条数
*/
private
Integer
maxCnt
;
/**
* 请求的消息时间范围的最小值(单位:秒)
*/
private
Integer
minTime
;
/**
* 请求的消息时间范围的最大值(单位:秒)
*/
private
Integer
maxTime
;
/**
* 上一次拉取到的最后一条消息的 MsgKey,续拉时需要填该字段
*/
private
String
LastMsgKey
;
}
ch-core/src/main/java/com/wwdz/ch/core/entity/im/IMUser.java
0 → 100644
View file @
68e5444b
package
com.wwdz.ch.core.entity.im
;
import
com.xxdxxs.entity.Entity
;
import
lombok.Data
;
@Data
public
class
IMUser
implements
Entity
{
/**
* 用户id
*/
private
String
userId
;
/**
* 昵称
*/
private
String
nick
;
/**
* 头像
*/
private
String
faceUrl
;
}
ch-core/src/main/java/com/wwdz/ch/core/entity/im/SendChatMsgRequestDto.java
0 → 100644
View file @
68e5444b
package
com.wwdz.ch.core.entity.im
;
import
com.xxdxxs.entity.Entity
;
import
lombok.Data
;
@Data
public
class
SendChatMsgRequestDto
implements
Entity
{
/**
* 1:把消息同步到 From_Account 在线终端和漫游上
* 2:消息不同步至 From_Account
* 若不填写默认情况下会将消息存 From_Account 漫游
*/
private
Integer
SyncOtherMachine
;
/**
* 消息发送方 UserID(用于指定发送消息方账号)
*/
private
String
From_Account
;
/**
* 消息接收方 UserID
*/
private
String
To_Account
;
/**
* 消息离线保存时长(单位:秒),最长为7天(604800秒)
* 若设置该字段为0,则消息只发在线用户,不保存离线
* 若设置该字段超过7天(604800秒),仍只保存7天
* 若不设置该字段,则默认保存7天
*/
private
Integer
MsgLifeTime
;
/**
* 消息序列号(32位无符号整数),后台会根据该字段去重及进行同秒内消息的排序,
* 详细规则请看本接口的功能说明。若不填该字段,则由后台填入随机数
*/
private
Integer
MsgSeq
;
/**
* 消息随机数(32位无符号整数),后台用于同一秒内的消息去重。请确保该字段填的是随机
*/
private
Integer
MsgRandom
;
/**
* 消息对象类型
* 枚举转换成字符串文本
*/
private
Integer
MsgType
;
/**
* 消息内容
*/
private
Object
MsgContent
;
}
ch-core/src/main/java/com/wwdz/ch/core/entity/im/vo/IMChatVo.java
0 → 100644
View file @
68e5444b
package
com.wwdz.ch.core.entity.im.vo
;
import
com.xxdxxs.entity.Entity
;
import
lombok.Data
;
@Data
public
class
IMChatVo
implements
Entity
{
}
ch-
wx-api/src/main/java/com/wwdz/ch/wx/im/ussrSig
/Base64URL.java
→
ch-
core/src/main/java/com/wwdz/ch/core/im
/Base64URL.java
View file @
68e5444b
package
com.wwdz.ch.
wx.im.ussrSig
;
package
com.wwdz.ch.
core.im
;
import
java.util.Base64
;
...
...
ch-
wx-api/src/main/java/com/wwdz/ch/wx/im/ussrSig
/TLSSigAPIv2.java
→
ch-
core/src/main/java/com/wwdz/ch/core/im
/TLSSigAPIv2.java
View file @
68e5444b
package
com.wwdz.ch.
wx.im.ussrSig
;
package
com.wwdz.ch.
core.im
;
import
org.json.JSONObject
;
import
javax.crypto.Mac
;
import
javax.crypto.spec.SecretKeySpec
;
import
java.nio.charset.StandardCharsets
;
import
java.
util.Base64
;
import
java.security.
*
;
import
java.
security.InvalidKeyException
;
import
java.security.
NoSuchAlgorithmException
;
import
java.util.Arrays
;
import
java.util.Base64
;
import
java.util.zip.Deflater
;
import
javax.crypto.Mac
;
import
javax.crypto.spec.SecretKeySpec
;
import
org.json.JSONObject
;
public
class
TLSSigAPIv2
{
final
private
long
sdkappid
;
...
...
ch-core/src/main/java/com/wwdz/ch/core/im/api/ChatUserApi.java
0 → 100644
View file @
68e5444b
package
com.wwdz.ch.core.im.api
;
import
com.wwdz.ch.core.entity.AbstractSubscribeMsg
;
import
com.wwdz.ch.core.entity.im.IMUser
;
import
com.wwdz.ch.core.type.Result
;
import
com.wwdz.ch.core.util.IMUtil
;
import
com.wwdz.ch.core.util.OkHttpUtil
;
import
com.wwdz.ch.core.util.RedisUtils
;
import
com.wwdz.ch.db.dao.UserDao
;
import
com.wwdz.ch.db.domain.User
;
import
com.xxdxxs.utils.JsonUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Component
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Random
;
/**
* 对话用户管理
*/
@Component
public
class
ChatUserApi
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
ChatUserApi
.
class
);
private
static
final
String
ACCOUNT_URL
=
"https://console.tim.qq.com/v4/im_open_login_svc/account_import"
;
@Value
(
"${dts.im.adminid}"
)
private
String
ADMIN_ID
;
@Value
(
"${dts.im.SDKAppID}"
)
private
Long
SDKAppID
;
@Value
(
"${dts.im.secret}"
)
private
String
SECRET
;
@Autowired
TLSSigApi
tlsSigApi
;
@Autowired
IMUtil
imUtil
;
@Autowired
UserDao
userDao
;
/**
* 导入用户信息到IM中
* @return
*/
public
Result
importUser
(
User
user
)
{
String
userSig
=
tlsSigApi
.
getUserSig
(
ADMIN_ID
);
Random
random
=
new
Random
(
4294967295L
);
long
randomNum
=
random
.
nextInt
();
StringBuffer
stringBuffer
=
new
StringBuffer
();
stringBuffer
.
append
(
"?sdkappid="
+
SDKAppID
);
stringBuffer
.
append
(
"&identifier="
+
ADMIN_ID
);
stringBuffer
.
append
(
"&usersig="
+
userSig
);
stringBuffer
.
append
(
"&random="
+
randomNum
);
stringBuffer
.
append
(
"&contenttype=json"
);
String
url
=
ACCOUNT_URL
+
stringBuffer
.
toString
();
logger
.
info
(
"============== IM导入用户请求url : {}"
,
url
);
OkHttpUtil
okHttpUtil
=
OkHttpUtil
.
builder
().
url
(
url
);
Map
<
String
,
Object
>
map
=
new
HashMap
<>();
map
.
put
(
"UserID"
,
imUtil
.
formatUserId
(
user
.
getId
()
+
""
));
map
.
put
(
"Nick"
,
user
.
getNickname
());
map
.
put
(
"FaceUrl"
,
user
.
getAvatar
());
logger
.
info
(
"============ IM导入用户内容 : {}"
,
JsonUtils
.
fromMap
(
map
));
okHttpUtil
.
addParams
(
map
);
okHttpUtil
.
post
(
true
);
String
responseStr
=
okHttpUtil
.
async
();
logger
.
info
(
"用户id : {}, IM导入用户 response :{}"
,
user
.
getId
(),
responseStr
);
String
actionStatus
=
JsonUtils
.
getValueByPath
(
responseStr
,
"ActionStatus"
);
String
errorCode
=
JsonUtils
.
getValueByPath
(
responseStr
,
"ErrorCode"
);
String
errorInfo
=
JsonUtils
.
getValueByPath
(
responseStr
,
"ErrorInfo"
);
if
(!
"OK"
.
equals
(
actionStatus
))
{
logger
.
error
(
"用户id : {}, IM导入用户失败, errorCode : {}, errmsg : {} "
,
user
.
getId
(),
errorCode
,
errorInfo
);
return
Result
.
failed
(
errorInfo
);
}
logger
.
info
(
"============= IM导入用户成功 ==========="
);
return
Result
.
success
();
}
/**
* IM用户初始化
* 导入表中已有全部的用户
* @return
*/
public
void
initUser
()
{
List
<
User
>
userList
=
userDao
.
queryAll
();
userList
.
forEach
(
user
->
{
importUser
(
user
);
});
}
}
ch-core/src/main/java/com/wwdz/ch/core/im/api/ConversationApi.java
0 → 100644
View file @
68e5444b
package
com.wwdz.ch.core.im.api
;
import
com.wwdz.ch.core.consts.IMEnum
;
import
com.wwdz.ch.core.entity.im.IMChatRequestDto
;
import
com.wwdz.ch.core.entity.im.SendChatMsgRequestDto
;
import
com.wwdz.ch.core.entity.im.IMChatMsg
;
import
com.wwdz.ch.core.type.Result
;
import
com.wwdz.ch.core.util.IMUtil
;
import
com.wwdz.ch.core.util.OkHttpUtil
;
import
com.xxdxxs.utils.EntityMapper
;
import
com.xxdxxs.utils.JsonUtils
;
import
com.xxdxxs.utils.MapUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Component
;
import
java.util.Arrays
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.Random
;
/**
* 会话api
*/
@Component
public
class
ConversationApi
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
ConversationApi
.
class
);
private
static
final
String
ACCOUNT_URL
=
"https://console.tim.qq.com/v4/openim/sendmsg"
;
private
static
final
String
GET_CHAT_LIST_URL
=
"https://console.tim.qq.com/v4/recentcontact/get_list"
;
@Value
(
"${dts.im.adminid}"
)
private
String
ADMIN_ID
;
@Value
(
"${dts.im.SDKAppID}"
)
private
Long
SDKAppID
;
@Autowired
TLSSigApi
tlsSigApi
;
@Autowired
IMUtil
imUtil
;
/**
* 发送对话信息
* @param sendChatMsgRequestDto
* @return
*/
public
Result
sendChatMsg
(
SendChatMsgRequestDto
sendChatMsgRequestDto
)
{
String
userSig
=
tlsSigApi
.
getUserSig
(
ADMIN_ID
);
Random
random
=
new
Random
(
4294967295L
);
int
randomNum
=
random
.
nextInt
();
StringBuffer
stringBuffer
=
new
StringBuffer
();
stringBuffer
.
append
(
"?sdkappid="
+
SDKAppID
);
stringBuffer
.
append
(
"&identifier="
+
ADMIN_ID
);
stringBuffer
.
append
(
"&usersig="
+
userSig
);
stringBuffer
.
append
(
"&random="
+
randomNum
);
stringBuffer
.
append
(
"&contenttype=json"
);
String
url
=
ACCOUNT_URL
+
stringBuffer
.
toString
();
OkHttpUtil
okHttpUtil
=
OkHttpUtil
.
builder
().
url
(
url
);
IMChatMsg
imChatMsg
=
imUtil
.
convert
(
sendChatMsgRequestDto
);
//消息同步至发送方
imChatMsg
.
setSyncOtherMachine
(
IMEnum
.
SyncOtherMachineEnum
.
SYNC
.
getCode
());
imChatMsg
.
setMsgRandom
(
randomNum
);
logger
.
info
(
"============ 发送对话信息内容 : {}"
,
JsonUtils
.
from
(
imChatMsg
));
okHttpUtil
.
addParams
(
MapUtils
.
fromEntity
(
imChatMsg
));
okHttpUtil
.
post
(
true
);
String
responseStr
=
okHttpUtil
.
async
();
logger
.
info
(
"发送对话信息 response :{}"
,
responseStr
);
String
actionStatus
=
JsonUtils
.
getValueByPath
(
responseStr
,
"ActionStatus"
);
String
errorCode
=
JsonUtils
.
getValueByPath
(
responseStr
,
"ErrorCode"
);
String
errorInfo
=
JsonUtils
.
getValueByPath
(
responseStr
,
"ErrorInfo"
);
if
(!
"OK"
.
equals
(
actionStatus
))
{
logger
.
error
(
"用户id : {}, 发送对话信息失败, errorCode : {}, errmsg : {} "
,
imChatMsg
.
getFrom_Account
(),
errorCode
,
errorInfo
);
return
Result
.
failed
(
errorInfo
);
}
logger
.
info
(
"============= 发送对话信息成功 ==========="
);
return
Result
.
success
();
}
/**
* 拉取会话列表
* @param imChatRequestDto
* @return
*/
public
Result
getChatList
(
IMChatRequestDto
imChatRequestDto
)
{
String
userSig
=
tlsSigApi
.
getUserSig
(
ADMIN_ID
);
Random
random
=
new
Random
(
4294967295L
);
int
randomNum
=
random
.
nextInt
();
StringBuffer
stringBuffer
=
new
StringBuffer
();
stringBuffer
.
append
(
"?sdkappid="
+
SDKAppID
);
stringBuffer
.
append
(
"&identifier="
+
ADMIN_ID
);
stringBuffer
.
append
(
"&usersig="
+
userSig
);
stringBuffer
.
append
(
"&random="
+
randomNum
);
stringBuffer
.
append
(
"&contenttype=json"
);
String
url
=
GET_CHAT_LIST_URL
+
stringBuffer
.
toString
();
OkHttpUtil
okHttpUtil
=
OkHttpUtil
.
builder
().
url
(
url
);
Map
<
String
,
Object
>
paramMap
=
new
HashMap
<>();
paramMap
.
put
(
"From_Account"
,
imUtil
.
formatUserId
(
imChatRequestDto
.
getUserId
()
+
""
));
paramMap
.
put
(
"TimeStamp"
,
0
);
paramMap
.
put
(
"StartIndex"
,
0
);
paramMap
.
put
(
"TopTimeStamp"
,
0
);
paramMap
.
put
(
"TopStartIndex"
,
0
);
paramMap
.
put
(
"AssistFlags"
,
15
);
logger
.
info
(
"============ 拉取会话列表参数 : {}"
,
JsonUtils
.
fromMap
(
paramMap
));
okHttpUtil
.
addParams
(
paramMap
);
okHttpUtil
.
post
(
true
);
String
responseStr
=
okHttpUtil
.
async
();
logger
.
info
(
"拉取会话列表 response :{}"
,
responseStr
);
String
actionStatus
=
JsonUtils
.
getValueByPath
(
responseStr
,
"ActionStatus"
);
String
errorCode
=
JsonUtils
.
getValueByPath
(
responseStr
,
"ErrorCode"
);
String
errorInfo
=
JsonUtils
.
getValueByPath
(
responseStr
,
"ErrorInfo"
);
if
(!
"OK"
.
equals
(
actionStatus
))
{
logger
.
error
(
"用户id : {}, 拉取会话列表, errorCode : {}, errmsg : {} "
,
imChatRequestDto
.
getUserId
(),
errorCode
,
errorInfo
);
return
Result
.
failed
(
errorInfo
);
}
logger
.
info
(
"============= 拉取会话列表成功 ==========="
);
return
Result
.
success
();
}
}
ch-core/src/main/java/com/wwdz/ch/core/im/api/TLSSigApi.java
0 → 100644
View file @
68e5444b
package
com.wwdz.ch.core.im.api
;
import
com.wwdz.ch.core.im.TLSSigAPIv2
;
import
com.wwdz.ch.core.util.IMUtil
;
import
com.wwdz.ch.core.util.RedisUtils
;
import
com.xxdxxs.utils.StringUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Component
;
import
java.util.concurrent.TimeUnit
;
/**
* 用户签名
*/
@Component
public
class
TLSSigApi
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
TLSSigApi
.
class
);
private
final
static
String
USERSIG_KEY
=
"IM:USERSIG:"
;
/**
* 30天有效期
*/
private
final
Long
EXPIRE
=
86400
*
30L
;
@Value
(
"${dts.im.SDKAppID}"
)
private
Long
SDKAppID
;
@Value
(
"${dts.im.secret}"
)
private
String
SECRET
;
@Value
(
"${dts.im.adminid}"
)
private
String
ADMIN_ID
;
@Autowired
RedisUtils
redisUtils
;
@Autowired
IMUtil
imUtil
;
/**
* 获取用户签名
* @param userId
* @return
*/
public
String
getUserSig
(
String
userId
)
{
//根据商户的appid从redis中获取商户的token
String
userSig
=
redisUtils
.
hasKey
(
getUserSigKey
(
userId
))?
redisUtils
.
get
(
getUserSigKey
(
userId
)).
toString
()
:
null
;
if
(
StringUtils
.
isEmpty
(
userSig
))
{
userSig
=
refreshUserSig
(
userId
);
}
return
userSig
;
}
/**
* 用户签名存在redis中的key
* @param userId
* @return
*/
private
String
getUserSigKey
(
String
userId
)
{
return
USERSIG_KEY
+
imUtil
.
formatUserId
(
userId
);
}
/**
* 刷新签名
* 有效期为24小时
* @param userId
* @return
*/
public
String
refreshUserSig
(
String
userId
)
{
TLSSigAPIv2
api
=
new
TLSSigAPIv2
(
SDKAppID
,
SECRET
);
String
userSig
=
api
.
genUserSig
(
userId
,
EXPIRE
);
logger
.
info
(
"IM刷新签名 : {}"
,
userSig
);
redisUtils
.
set
(
getUserSigKey
(
userId
),
userSig
,
EXPIRE
-
10
,
TimeUnit
.
SECONDS
);
return
userSig
;
}
}
ch-core/src/main/java/com/wwdz/ch/core/util/IMUtil.java
0 → 100644
View file @
68e5444b
package
com.wwdz.ch.core.util
;
import
com.wwdz.ch.core.consts.IMEnum
;
import
com.wwdz.ch.core.entity.im.SendChatMsgRequestDto
;
import
com.wwdz.ch.core.entity.im.IMChatMsg
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Component
;
import
java.util.Arrays
;
import
java.util.HashMap
;
import
java.util.Map
;
@Component
public
class
IMUtil
{
@Value
(
"${dts.im.prefix}"
)
private
String
PREFIX
;
/**
* 格式化用户id
* 转换为im对话中的用户id
* @param userId
* @return
*/
public
String
formatUserId
(
String
userId
)
{
return
PREFIX
+
userId
;
}
/**
* 参数userId格式为XX_userid
* 还原成系统中的userid,去除前缀
* @param userId
* @return
*/
public
long
getAppletUserId
(
String
userId
)
{
String
appletUserId
=
userId
.
split
(
"_"
)[
1
];
return
Long
.
valueOf
(
appletUserId
);
}
/**
* SendChatMsgRequestDto 转换成 IMChatMsg
* @param dto
* @return
*/
public
IMChatMsg
convert
(
SendChatMsgRequestDto
dto
)
{
IMChatMsg
imChatMsg
=
new
IMChatMsg
();
//userid需要转换成IM的用户ID
imChatMsg
.
setTo_Account
(
formatUserId
(
dto
.
getTo_Account
()));
imChatMsg
.
setFrom_Account
(
formatUserId
(
dto
.
getFrom_Account
()));
Map
<
String
,
Object
>
msgContentMap
=
new
HashMap
<>();
msgContentMap
.
put
(
"MsgType"
,
IMEnum
.
MsgTypeEnum
.
getValueByCode
(
dto
.
getMsgType
()));
msgContentMap
.
put
(
"MsgContent"
,
new
HashMap
(){{
put
(
"Text"
,
dto
.
getMsgContent
());}});
imChatMsg
.
setMsgBody
(
Arrays
.
asList
(
msgContentMap
));
return
imChatMsg
;
}
}
ch-core/src/main/resources/application-dev.yml
View file @
68e5444b
...
...
@@ -22,6 +22,13 @@ dts:
officialaccount-key
:
noeN1amYRvzrVmE2GnC5VnsIfgPEmv6bhX54wJOARlM
get-officialaccount-accesstoken-url
:
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential
#腾讯IM配置
im
:
SDKAppID
:
1400489950
secret
:
b5873a44e46efd086015a51e171e6e09fdeb4dce778752c891e63ed17aa1a81e
prefix
:
cjxc-applet-dev_
adminid
:
cjxc
#通知相关配置
notify
:
mail
:
...
...
ch-core/src/main/resources/application-prod.yml
View file @
68e5444b
...
...
@@ -21,6 +21,13 @@ dts:
officialaccount-key
:
noeN1amYRvzrVmE2GnC5VnsIfgPEmv6bhX54wJOARlM
get-officialaccount-accesstoken-url
:
https://api.weixin.qq.com/cgi-bin/stable_token?grant_type=client_credential
#腾讯IM配置
im
:
SDKAppID
:
1400489950
secret
:
b5873a44e46efd086015a51e171e6e09fdeb4dce778752c891e63ed17aa1a81e
prefix
:
cjxc-applet_
adminid
:
cjxc
#通知相关配置
notify
:
mail
:
...
...
ch-dao/src/main/java/com/wwdz/ch/db/dao/AiAssistantDao.java
View file @
68e5444b
...
...
@@ -7,4 +7,6 @@ import java.util.List;
public
interface
AiAssistantDao
{
List
<
AiAssistant
>
findList
(
AiAssistantRequestDto
dto
);
AiAssistant
findByCode
(
String
code
);
}
ch-dao/src/main/java/com/wwdz/ch/db/dao/UserDao.java
View file @
68e5444b
...
...
@@ -2,6 +2,8 @@ package com.wwdz.ch.db.dao;
import
com.wwdz.ch.db.domain.User
;
import
java.util.List
;
public
interface
UserDao
{
/**
* 通过oid查询未删除的记录
...
...
@@ -71,4 +73,7 @@ public interface UserDao {
boolean
isExistedByMobile
(
String
beforeMobile
,
String
afterMobile
);
List
<
User
>
queryAll
();
}
ch-dao/src/main/java/com/wwdz/ch/db/domain/AiAssistant.java
View file @
68e5444b
package
com.wwdz.ch.db.domain
;
import
java.io.Serializable
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Date
;
...
...
@@ -9,12 +10,17 @@ import lombok.Data;
/**
* @author shiyu
* @date 2023/10/1
6
* @date 2023/10/1
8
*/
@Data
public
class
AiAssistant
implements
Entity
{
private
Integer
id
;
/**
* 编号
*/
private
String
code
;
/**
* 头像
*/
...
...
@@ -49,6 +55,7 @@ public class AiAssistant implements Entity {
sb
.
append
(
" ["
);
sb
.
append
(
"Hash = "
).
append
(
hashCode
());
sb
.
append
(
", id="
).
append
(
id
);
sb
.
append
(
", code="
).
append
(
code
);
sb
.
append
(
", avatar="
).
append
(
avatar
);
sb
.
append
(
", name="
).
append
(
name
);
sb
.
append
(
", profile="
).
append
(
profile
);
...
...
@@ -72,6 +79,7 @@ public class AiAssistant implements Entity {
}
AiAssistant
other
=
(
AiAssistant
)
that
;
return
(
this
.
getId
()
==
null
?
other
.
getId
()
==
null
:
this
.
getId
().
equals
(
other
.
getId
()))
&&
(
this
.
getCode
()
==
null
?
other
.
getCode
()
==
null
:
this
.
getCode
().
equals
(
other
.
getCode
()))
&&
(
this
.
getAvatar
()
==
null
?
other
.
getAvatar
()
==
null
:
this
.
getAvatar
().
equals
(
other
.
getAvatar
()))
&&
(
this
.
getName
()
==
null
?
other
.
getName
()
==
null
:
this
.
getName
().
equals
(
other
.
getName
()))
&&
(
this
.
getProfile
()
==
null
?
other
.
getProfile
()
==
null
:
this
.
getProfile
().
equals
(
other
.
getProfile
()))
...
...
@@ -84,6 +92,7 @@ public class AiAssistant implements Entity {
final
int
prime
=
31
;
int
result
=
1
;
result
=
prime
*
result
+
((
getId
()
==
null
)
?
0
:
getId
().
hashCode
());
result
=
prime
*
result
+
((
getCode
()
==
null
)
?
0
:
getCode
().
hashCode
());
result
=
prime
*
result
+
((
getAvatar
()
==
null
)
?
0
:
getAvatar
().
hashCode
());
result
=
prime
*
result
+
((
getName
()
==
null
)
?
0
:
getName
().
hashCode
());
result
=
prime
*
result
+
((
getProfile
()
==
null
)
?
0
:
getProfile
().
hashCode
());
...
...
@@ -101,6 +110,7 @@ public class AiAssistant implements Entity {
*/
public
enum
Column
{
id
(
"id"
,
"id"
,
"INTEGER"
,
false
),
code
(
"code"
,
"code"
,
"VARCHAR"
,
false
),
avatar
(
"avatar"
,
"avatar"
,
"VARCHAR"
,
false
),
name
(
"name"
,
"name"
,
"VARCHAR"
,
true
),
profile
(
"profile"
,
"profile"
,
"VARCHAR"
,
false
),
...
...
ch-dao/src/main/java/com/wwdz/ch/db/domain/AiAssistantExample.java
View file @
68e5444b
...
...
@@ -280,6 +280,148 @@ public class AiAssistantExample {
return
(
Criteria
)
this
;
}
public
Criteria
andCodeIsNull
()
{
addCriterion
(
"code is null"
);
return
(
Criteria
)
this
;
}
public
Criteria
andCodeIsNotNull
()
{
addCriterion
(
"code is not null"
);
return
(
Criteria
)
this
;
}
public
Criteria
andCodeEqualTo
(
String
value
)
{
addCriterion
(
"code ="
,
value
,
"code"
);
return
(
Criteria
)
this
;
}
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table ai_assistant
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
public
Criteria
andCodeEqualToColumn
(
AiAssistant
.
Column
column
)
{
addCriterion
(
new
StringBuilder
(
"code = "
).
append
(
column
.
getEscapedColumnName
()).
toString
());
return
(
Criteria
)
this
;
}
public
Criteria
andCodeNotEqualTo
(
String
value
)
{
addCriterion
(
"code <>"
,
value
,
"code"
);
return
(
Criteria
)
this
;
}
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table ai_assistant
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
public
Criteria
andCodeNotEqualToColumn
(
AiAssistant
.
Column
column
)
{
addCriterion
(
new
StringBuilder
(
"code <> "
).
append
(
column
.
getEscapedColumnName
()).
toString
());
return
(
Criteria
)
this
;
}
public
Criteria
andCodeGreaterThan
(
String
value
)
{
addCriterion
(
"code >"
,
value
,
"code"
);
return
(
Criteria
)
this
;
}
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table ai_assistant
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
public
Criteria
andCodeGreaterThanColumn
(
AiAssistant
.
Column
column
)
{
addCriterion
(
new
StringBuilder
(
"code > "
).
append
(
column
.
getEscapedColumnName
()).
toString
());
return
(
Criteria
)
this
;
}
public
Criteria
andCodeGreaterThanOrEqualTo
(
String
value
)
{
addCriterion
(
"code >="
,
value
,
"code"
);
return
(
Criteria
)
this
;
}
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table ai_assistant
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
public
Criteria
andCodeGreaterThanOrEqualToColumn
(
AiAssistant
.
Column
column
)
{
addCriterion
(
new
StringBuilder
(
"code >= "
).
append
(
column
.
getEscapedColumnName
()).
toString
());
return
(
Criteria
)
this
;
}
public
Criteria
andCodeLessThan
(
String
value
)
{
addCriterion
(
"code <"
,
value
,
"code"
);
return
(
Criteria
)
this
;
}
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table ai_assistant
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
public
Criteria
andCodeLessThanColumn
(
AiAssistant
.
Column
column
)
{
addCriterion
(
new
StringBuilder
(
"code < "
).
append
(
column
.
getEscapedColumnName
()).
toString
());
return
(
Criteria
)
this
;
}
public
Criteria
andCodeLessThanOrEqualTo
(
String
value
)
{
addCriterion
(
"code <="
,
value
,
"code"
);
return
(
Criteria
)
this
;
}
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table ai_assistant
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
public
Criteria
andCodeLessThanOrEqualToColumn
(
AiAssistant
.
Column
column
)
{
addCriterion
(
new
StringBuilder
(
"code <= "
).
append
(
column
.
getEscapedColumnName
()).
toString
());
return
(
Criteria
)
this
;
}
public
Criteria
andCodeLike
(
String
value
)
{
addCriterion
(
"code like"
,
value
,
"code"
);
return
(
Criteria
)
this
;
}
public
Criteria
andCodeNotLike
(
String
value
)
{
addCriterion
(
"code not like"
,
value
,
"code"
);
return
(
Criteria
)
this
;
}
public
Criteria
andCodeIn
(
List
<
String
>
values
)
{
addCriterion
(
"code in"
,
values
,
"code"
);
return
(
Criteria
)
this
;
}
public
Criteria
andCodeNotIn
(
List
<
String
>
values
)
{
addCriterion
(
"code not in"
,
values
,
"code"
);
return
(
Criteria
)
this
;
}
public
Criteria
andCodeBetween
(
String
value1
,
String
value2
)
{
addCriterion
(
"code between"
,
value1
,
value2
,
"code"
);
return
(
Criteria
)
this
;
}
public
Criteria
andCodeNotBetween
(
String
value1
,
String
value2
)
{
addCriterion
(
"code not between"
,
value1
,
value2
,
"code"
);
return
(
Criteria
)
this
;
}
public
Criteria
andAvatarIsNull
()
{
addCriterion
(
"avatar is null"
);
return
(
Criteria
)
this
;
...
...
ch-dao/src/main/java/com/wwdz/ch/db/dto/request/AiAssistantRequestDto.java
View file @
68e5444b
...
...
@@ -9,6 +9,11 @@ public class AiAssistantRequestDto extends BaseRequestDto implements Entity {
private
Integer
id
;
/**
* 编号
*/
private
String
code
;
/**
* 名称
*/
...
...
ch-dao/src/main/java/com/wwdz/ch/db/impl/AiAssistantDaoImpl.java
View file @
68e5444b
...
...
@@ -24,4 +24,11 @@ public class AiAssistantDaoImpl implements AiAssistantDao {
PageHelper
.
startPage
(
dto
.
getPage
(),
dto
.
getLimit
());
return
aiAssistantMapper
.
selectByExample
(
aiAssistantExample
);
}
@Override
public
AiAssistant
findByCode
(
String
code
)
{
AiAssistantExample
aiAssistantExample
=
new
AiAssistantExample
();
aiAssistantExample
.
createCriteria
().
andCodeEqualTo
(
code
);
return
aiAssistantMapper
.
selectOneByExample
(
aiAssistantExample
);
}
}
ch-dao/src/main/java/com/wwdz/ch/db/impl/UserDaoImpl.java
View file @
68e5444b
...
...
@@ -9,6 +9,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.stereotype.Repository
;
import
java.util.Date
;
import
java.util.List
;
@Repository
public
class
UserDaoImpl
implements
UserDao
{
...
...
@@ -72,4 +73,11 @@ public class UserDaoImpl implements UserDao {
criteria
.
andDeletedEqualTo
(
false
);
return
userMapper
.
countByExample
(
example
)
>
0
;
}
@Override
public
List
<
User
>
queryAll
()
{
UserExample
example
=
new
UserExample
();
example
.
createCriteria
().
andDeletedEqualTo
(
false
);
return
userMapper
.
selectByExample
(
example
);
}
}
ch-dao/src/main/resources/com/wwdz/ch/db/mapper/AiAssistantMapper.xml
View file @
68e5444b
...
...
@@ -3,6 +3,7 @@
<mapper
namespace=
"com.wwdz.ch.db.mapper.AiAssistantMapper"
>
<resultMap
id=
"BaseResultMap"
type=
"com.wwdz.ch.db.domain.AiAssistant"
>
<id
column=
"id"
jdbcType=
"INTEGER"
property=
"id"
/>
<result
column=
"code"
jdbcType=
"VARCHAR"
property=
"code"
/>
<result
column=
"avatar"
jdbcType=
"VARCHAR"
property=
"avatar"
/>
<result
column=
"name"
jdbcType=
"VARCHAR"
property=
"name"
/>
<result
column=
"profile"
jdbcType=
"VARCHAR"
property=
"profile"
/>
...
...
@@ -68,7 +69,7 @@
</where>
</sql>
<sql
id=
"Base_Column_List"
>
id, avatar, `name`, profile, `type`, create_time
id,
code,
avatar, `name`, profile, `type`, create_time
</sql>
<select
id=
"selectByExample"
parameterType=
"com.wwdz.ch.db.domain.AiAssistantExample"
resultMap=
"BaseResultMap"
>
select
...
...
@@ -103,7 +104,7 @@
</foreach>
</when>
<otherwise>
id, avatar, `name`, profile, `type`, create_time
id,
code,
avatar, `name`, profile, `type`, create_time
</otherwise>
</choose>
from ai_assistant
...
...
@@ -134,7 +135,7 @@
</foreach>
</when>
<otherwise>
id, avatar, `name`, profile, `type`, create_time
id,
code,
avatar, `name`, profile, `type`, create_time
</otherwise>
</choose>
from ai_assistant
...
...
@@ -154,10 +155,12 @@
<selectKey
keyProperty=
"id"
order=
"AFTER"
resultType=
"java.lang.Integer"
>
SELECT LAST_INSERT_ID()
</selectKey>
insert into ai_assistant (avatar, `name`, profile,
`type`, create_time)
values (#{avatar,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{profile,jdbcType=VARCHAR},
#{type,jdbcType=INTEGER}, #{createTime,jdbcType=TIMESTAMP})
insert into ai_assistant (code, avatar, `name`,
profile, `type`, create_time
)
values (#{code,jdbcType=VARCHAR}, #{avatar,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR},
#{profile,jdbcType=VARCHAR}, #{type,jdbcType=INTEGER}, #{createTime,jdbcType=TIMESTAMP}
)
</insert>
<insert
id=
"insertSelective"
parameterType=
"com.wwdz.ch.db.domain.AiAssistant"
>
<selectKey
keyProperty=
"id"
order=
"AFTER"
resultType=
"java.lang.Integer"
>
...
...
@@ -165,6 +168,9 @@
</selectKey>
insert into ai_assistant
<trim
prefix=
"("
suffix=
")"
suffixOverrides=
","
>
<if
test=
"code != null"
>
code,
</if>
<if
test=
"avatar != null"
>
avatar,
</if>
...
...
@@ -182,6 +188,9 @@
</if>
</trim>
<trim
prefix=
"values ("
suffix=
")"
suffixOverrides=
","
>
<if
test=
"code != null"
>
#{code,jdbcType=VARCHAR},
</if>
<if
test=
"avatar != null"
>
#{avatar,jdbcType=VARCHAR},
</if>
...
...
@@ -211,6 +220,9 @@
<if
test=
"record.id != null"
>
id = #{record.id,jdbcType=INTEGER},
</if>
<if
test=
"record.code != null"
>
code = #{record.code,jdbcType=VARCHAR},
</if>
<if
test=
"record.avatar != null"
>
avatar = #{record.avatar,jdbcType=VARCHAR},
</if>
...
...
@@ -234,6 +246,7 @@
<update
id=
"updateByExample"
parameterType=
"map"
>
update ai_assistant
set id = #{record.id,jdbcType=INTEGER},
code = #{record.code,jdbcType=VARCHAR},
avatar = #{record.avatar,jdbcType=VARCHAR},
`name` = #{record.name,jdbcType=VARCHAR},
profile = #{record.profile,jdbcType=VARCHAR},
...
...
@@ -246,6 +259,9 @@
<update
id=
"updateByPrimaryKeySelective"
parameterType=
"com.wwdz.ch.db.domain.AiAssistant"
>
update ai_assistant
<set>
<if
test=
"code != null"
>
code = #{code,jdbcType=VARCHAR},
</if>
<if
test=
"avatar != null"
>
avatar = #{avatar,jdbcType=VARCHAR},
</if>
...
...
@@ -266,7 +282,8 @@
</update>
<update
id=
"updateByPrimaryKey"
parameterType=
"com.wwdz.ch.db.domain.AiAssistant"
>
update ai_assistant
set avatar = #{avatar,jdbcType=VARCHAR},
set code = #{code,jdbcType=VARCHAR},
avatar = #{avatar,jdbcType=VARCHAR},
`name` = #{name,jdbcType=VARCHAR},
profile = #{profile,jdbcType=VARCHAR},
`type` = #{type,jdbcType=INTEGER},
...
...
@@ -306,7 +323,7 @@
</foreach>
</when>
<otherwise>
id, avatar, `name`, profile, `type`, create_time
id,
code,
avatar, `name`, profile, `type`, create_time
</otherwise>
</choose>
from ai_assistant
...
...
@@ -319,4 +336,5 @@
limit 1
</select>
</mapper>
\ No newline at end of file
ch-wx-api/src/main/java/com/wwdz/ch/wx/config/WebMvcConfiguration.java
View file @
68e5444b
...
...
@@ -41,7 +41,8 @@ public class WebMvcConfiguration implements WebMvcConfigurer {
,
"/wx/user/loginByWx"
,
"/wx/user/loginByMobile"
,
"/wx/user/loginRegCaptcha"
,
"/wx/user/updateRegCaptcha"
,
"/wx/user/login"
,
"/wx/user/fillCode"
,
"/officialAccountCallback/**"
,
"/wx/officialAccount/**"
,
"/wx/item/**"
"/wx/item/**"
,
"/wx/aiAssistant/**"
);
}
}
ch-wx-api/src/main/java/com/wwdz/ch/wx/impl/IMServiceImpl.java
0 → 100644
View file @
68e5444b
package
com.wwdz.ch.wx.impl
;
import
com.wwdz.ch.core.consts.IMEnum
;
import
com.wwdz.ch.core.entity.im.SendChatMsgRequestDto
;
import
com.wwdz.ch.core.entity.im.IMChatRequestDto
;
import
com.wwdz.ch.core.im.api.ConversationApi
;
import
com.wwdz.ch.core.im.api.TLSSigApi
;
import
com.wwdz.ch.core.type.Result
;
import
com.wwdz.ch.db.dao.AiAssistantDao
;
import
com.wwdz.ch.db.domain.AiAssistant
;
import
com.wwdz.ch.wx.service.IMService
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
java.util.HashMap
;
import
java.util.Map
;
/**
* 会话
*/
@Service
public
class
IMServiceImpl
implements
IMService
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
IMServiceImpl
.
class
);
@Autowired
ConversationApi
conversationApi
;
@Autowired
AiAssistantDao
aiAssistantDao
;
@Autowired
TLSSigApi
tlsSigApi
;
/**
* 新增ai会话,发送默认打招呼的消息
* @param dto
* @return
*/
@Override
public
Result
addAiChat
(
SendChatMsgRequestDto
dto
)
{
try
{
AiAssistant
aiAssistant
=
aiAssistantDao
.
findByCode
(
dto
.
getFrom_Account
());
String
msgContent
=
aiAssistant
.
getProfile
();
dto
.
setMsgContent
(
msgContent
);
dto
.
setMsgType
(
IMEnum
.
MsgTypeEnum
.
TIMTextElem
.
getCode
());
Result
sendResult
=
conversationApi
.
sendChatMsg
(
dto
);
if
(!
sendResult
.
getSuccess
())
{
return
Result
.
failed
(
"新增会话失败"
);
}
return
Result
.
success
();
}
catch
(
Exception
e
)
{
logger
.
info
(
"新增ai会话失败 error:{}"
,
e
);
}
return
Result
.
failed
();
}
@Override
public
Result
findChatList
(
IMChatRequestDto
dto
)
{
try
{
Result
result
=
conversationApi
.
getChatList
(
dto
);
}
catch
(
Exception
e
)
{
logger
.
error
(
"获取会话列表失败:{}"
,
e
);
}
return
Result
.
failed
();
}
@Override
public
Result
getUserSig
(
IMChatRequestDto
dto
)
{
try
{
String
userSig
=
tlsSigApi
.
getUserSig
(
String
.
valueOf
(
dto
.
getUserId
()));
Map
<
String
,
String
>
map
=
new
HashMap
<>();
map
.
put
(
"userSig"
,
userSig
);
return
Result
.
success
(
map
);
}
catch
(
Exception
e
)
{
logger
.
error
(
"获取用户签名失败:{}"
,
e
);
}
return
Result
.
failed
();
}
}
ch-wx-api/src/main/java/com/wwdz/ch/wx/service/IMService.java
0 → 100644
View file @
68e5444b
package
com.wwdz.ch.wx.service
;
import
com.wwdz.ch.core.entity.im.SendChatMsgRequestDto
;
import
com.wwdz.ch.core.entity.im.IMChatRequestDto
;
import
com.wwdz.ch.core.type.Result
;
public
interface
IMService
{
/**
* 新增ai会话
* 发送默认打招呼的消息
*/
Result
addAiChat
(
SendChatMsgRequestDto
dto
);
/**
* 查询会话列表
* @param dto
* @return
*/
Result
findChatList
(
IMChatRequestDto
dto
);
/**
* 获取用户签名
* @param dto
* @return
*/
Result
getUserSig
(
IMChatRequestDto
dto
);
}
ch-wx-api/src/main/java/com/wwdz/ch/wx/web/AiAssistantController.java
View file @
68e5444b
...
...
@@ -49,4 +49,6 @@ public class AiAssistantController {
}
}
ch-wx-api/src/main/java/com/wwdz/ch/wx/web/IMController.java
0 → 100644
View file @
68e5444b
package
com.wwdz.ch.wx.web
;
import
com.alibaba.fastjson.JSON
;
import
com.wwdz.ch.core.consts.ResultCode
;
import
com.wwdz.ch.core.entity.im.SendChatMsgRequestDto
;
import
com.wwdz.ch.core.entity.im.IMChatRequestDto
;
import
com.wwdz.ch.core.type.Result
;
import
com.wwdz.ch.wx.service.AiAssistantService
;
import
com.wwdz.ch.wx.service.AiDefaultQuestionService
;
import
com.wwdz.ch.wx.service.IMService
;
import
com.xxdxxs.utils.StringUtils
;
import
io.swagger.annotations.ApiOperation
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.RequestBody
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
@RestController
@RequestMapping
(
"/wx/im"
)
public
class
IMController
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
IMController
.
class
);
@Autowired
AiAssistantService
aiAssistantService
;
@Autowired
AiDefaultQuestionService
aiDefaultQuestionService
;
@Autowired
IMService
imService
;
@ApiOperation
(
value
=
"查询会话列表"
)
@PostMapping
(
"/findChatList"
)
public
Result
findList
(
@RequestBody
IMChatRequestDto
dto
)
{
logger
.
info
(
"【请求开始】查询会话列表,请求参数:{}"
,
JSON
.
toJSONString
(
dto
));
return
imService
.
findChatList
(
dto
);
}
@ApiOperation
(
value
=
"新增AI会话"
)
@PostMapping
(
"/addChat"
)
public
Result
addChat
(
@RequestBody
SendChatMsgRequestDto
dto
)
{
logger
.
info
(
"【请求开始】新增AI会话,请求参数:{}"
,
JSON
.
toJSONString
(
dto
));
if
(!
StringUtils
.
isAllNotEmpty
(
dto
.
getFrom_Account
(),
dto
.
getTo_Account
()))
{
return
Result
.
failed
(
ResultCode
.
PARAM_ERROR
);
}
return
imService
.
addAiChat
(
dto
);
}
@ApiOperation
(
value
=
"获取用户签名"
)
@PostMapping
(
"/getUserSig"
)
public
Result
getUserSig
(
@RequestBody
IMChatRequestDto
dto
)
{
logger
.
info
(
"【请求开始】获取用户签名,请求参数:{}"
,
JSON
.
toJSONString
(
dto
));
if
(
StringUtils
.
isEmpty
(
dto
.
getUserId
()))
{
return
Result
.
failed
(
ResultCode
.
PARAM_ERROR
);
}
return
imService
.
getUserSig
(
dto
);
}
}
ch-wx-api/src/test/java/com/wwdz/ch/wx/api/ChatApiTest.java
View file @
68e5444b
package
com.wwdz.ch.wx.api
;
import
com.wwdz.ch.core.consts.IMEnum
;
import
com.wwdz.ch.core.entity.im.IMChatRequestDto
;
import
com.wwdz.ch.core.entity.im.SendChatMsgRequestDto
;
import
com.wwdz.ch.core.im.api.ChatUserApi
;
import
com.wwdz.ch.core.im.api.ConversationApi
;
import
com.wwdz.ch.core.im.api.TLSSigApi
;
import
com.wwdz.ch.db.dao.UserDao
;
import
com.wwdz.ch.db.domain.User
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.boot.test.context.SpringBootTest
;
import
org.springframework.test.context.junit4.SpringJUnit4ClassRunner
;
import
static
org
.
junit
.
Assert
.*;
@SpringBootTest
@RunWith
(
SpringJUnit4ClassRunner
.
class
)
...
...
@@ -15,12 +22,71 @@ public class ChatApiTest {
@Autowired
ChatApi
chatApi
;
@Autowired
ChatUserApi
chatUserApi
;
@Autowired
ConversationApi
conversationApi
;
@Autowired
UserDao
userDao
;
@Autowired
TLSSigApi
tlsSigApi
;
@Test
public
void
chatWithModel
()
{
String
question
=
"刀币的由来"
;
chatApi
.
chatWithModel
(
question
);
}
@Test
public
void
getUserSig
()
{
tlsSigApi
.
refreshUserSig
(
"cjxc"
);
}
/**
* 导入IM用户
*/
@Test
public
void
importUser
()
{
User
user
=
userDao
.
queryById
(
251L
);
chatUserApi
.
importUser
(
user
);
}
/**
* 导入系统所有用户
*/
@Test
public
void
initAllUser
()
{
chatUserApi
.
initUser
();
}
/**
* 发送IM消息
*/
@Test
public
void
sendChatMsg
()
{
SendChatMsgRequestDto
sendChatMsgRequestDto
=
new
SendChatMsgRequestDto
();
sendChatMsgRequestDto
.
setTo_Account
(
"241"
);
sendChatMsgRequestDto
.
setFrom_Account
(
"251"
);
sendChatMsgRequestDto
.
setMsgType
(
IMEnum
.
MsgTypeEnum
.
TIMTextElem
.
getCode
());
String
msgContent
=
"测试消息4444444的数据, 是否可以接收到"
;
sendChatMsgRequestDto
.
setMsgContent
(
msgContent
);
conversationApi
.
sendChatMsg
(
sendChatMsgRequestDto
);
}
/**
* 拉取会话列表
*/
@Test
public
void
getChatList
()
{
IMChatRequestDto
imChatRequestDto
=
new
IMChatRequestDto
();
imChatRequestDto
.
setUserId
(
251L
);
conversationApi
.
getChatList
(
imChatRequestDto
);
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment