Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yd-communication
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
xingmin
yd-communication
Commits
63e13557
Commit
63e13557
authored
Aug 10, 2026
by
zhangxingmin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
push
parent
e00f6e6d
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
226 additions
and
54 deletions
+226
-54
yd-communication-api/src/main/java/com/yd/communication/api/controller/ApiCoSessionController.java
+4
-3
yd-communication-api/src/main/java/com/yd/communication/api/service/ApiCoSessionService.java
+1
-0
yd-communication-api/src/main/java/com/yd/communication/api/service/impl/ApiCoSessionServiceImpl.java
+123
-42
yd-communication-api/src/main/java/com/yd/communication/api/utils/QRCodeUtils.java
+43
-0
yd-communication-feign/src/main/java/com/yd/communication/feign/client/ApiCoSessionFeignClient.java
+1
-1
yd-communication-feign/src/main/java/com/yd/communication/feign/constant/RedisConstants.java
+2
-0
yd-communication-feign/src/main/java/com/yd/communication/feign/dto/RoomRedisInfoDTO.java
+10
-0
yd-communication-feign/src/main/java/com/yd/communication/feign/enums/RedisEnum.java
+3
-1
yd-communication-feign/src/main/java/com/yd/communication/feign/request/JoinRequest.java
+6
-6
yd-communication-feign/src/main/java/com/yd/communication/feign/response/CreateResponse.java
+11
-0
yd-communication-service/pom.xml
+9
-0
yd-communication-service/src/main/java/com/yd/communication/service/model/CoSession.java
+13
-1
No files found.
yd-communication-api/src/main/java/com/yd/communication/api/controller/ApiCoSessionController.java
View file @
63e13557
...
...
@@ -31,16 +31,17 @@ public class ApiCoSessionController implements ApiCoSessionFeignClient {
private
ApiCoSessionService
apiCoSessionService
;
/**
*
客户创建会话(生成共享码)
* @param request
*
创建协同会话
* @param request
创建会话请求
* @return
*/
@Override
public
Result
<
CreateResponse
>
create
(
CreateRequest
request
)
{
return
apiCoSessionService
.
create
(
request
);
}
/**
*
顾问加入会话(输入共享码加入房间,可以多次加入)
*
加入协同会话
* @param request
* @return
*/
...
...
yd-communication-api/src/main/java/com/yd/communication/api/service/ApiCoSessionService.java
View file @
63e13557
...
...
@@ -14,6 +14,7 @@ import com.yd.communication.service.model.CoSession;
public
interface
ApiCoSessionService
{
Result
<
CreateResponse
>
create
(
CreateRequest
request
);
Result
<
JoinResponse
>
join
(
JoinRequest
request
);
...
...
yd-communication-api/src/main/java/com/yd/communication/api/service/impl/ApiCoSessionServiceImpl.java
View file @
63e13557
...
...
@@ -4,10 +4,12 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import
com.yd.common.enums.CommonEnum
;
import
com.yd.common.exception.BusinessException
;
import
com.yd.common.result.Result
;
import
com.yd.common.utils.ByteArrayMultipartFile
;
import
com.yd.common.utils.RandomStringGenerator
;
import
com.yd.common.utils.RedisUtil
;
import
com.yd.communication.api.service.ApiCoSessionService
;
import
com.yd.communication.api.utils.ClientInfoUtils
;
import
com.yd.communication.api.utils.QRCodeUtils
;
import
com.yd.communication.feign.dto.RoomRedisInfoDTO
;
import
com.yd.communication.feign.enums.CoSessionStatusEnum
;
import
com.yd.communication.feign.enums.ControlHolderTypeEnum
;
...
...
@@ -25,11 +27,17 @@ import com.yd.communication.service.service.ICoOperationLogService;
import
com.yd.communication.service.service.ICoSessionService
;
import
com.yd.communication.service.service.IRecordingTaskService
;
import
com.yd.communication.service.utils.RandomUtil
;
import
com.yd.oss.feign.client.ApiOssFeignClient
;
import
com.yd.oss.feign.request.ApiUploadFileRequest
;
import
com.yd.oss.feign.response.ApiUploadResponse
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.web.multipart.MultipartFile
;
import
javax.annotation.Resource
;
import
java.time.LocalDateTime
;
import
java.util.UUID
;
...
...
@@ -50,40 +58,11 @@ public class ApiCoSessionServiceImpl implements ApiCoSessionService {
@Resource
private
RedisUtil
redisUtil
;
/**
* 客户创建会话(生成共享码)
*/
@Override
@Transactional
(
rollbackFor
=
Exception
.
class
)
public
Result
<
CreateResponse
>
create
(
CreateRequest
request
)
{
log
.
info
(
"【创建会话】收到创建请求, request={}"
,
request
);
try
{
CoSession
session
=
createSession
(
request
.
getScope
(),
request
.
getResourceType
(),
request
.
getResourceId
(),
request
.
getResourceInit
(),
request
.
getOwnerId
(),
request
.
getOwnerType
(),
request
.
getUserId
(),
request
.
getToken
()
);
if
(
session
==
null
)
{
log
.
warn
(
"【创建会话】创建失败,返回空会话"
);
return
Result
.
success
();
}
CreateResponse
response
=
new
CreateResponse
();
response
.
setRoomId
(
session
.
getRoomId
());
response
.
setRoomPwd
(
session
.
getRoomPwd
());
response
.
setSessionBizId
(
session
.
getCoSessionBizId
());
response
.
setStatus
(
session
.
getStatus
());
log
.
info
(
"【创建会话】成功,roomId={}, roomPwd={}, sessionBizId={}"
,
session
.
getRoomId
(),
session
.
getRoomPwd
(),
session
.
getCoSessionBizId
());
return
Result
.
success
(
response
);
}
catch
(
Exception
e
)
{
log
.
error
(
"【创建会话】异常"
,
e
);
throw
e
;
}
}
@Resource
private
ApiOssFeignClient
apiOssFeignClient
;
@Value
(
"${co.room.base-url:https://default-domain.com/co/join}"
)
private
String
roomBaseUrl
;
/**
* 客户创建会话(生成共享码)——内部方法
...
...
@@ -133,7 +112,9 @@ public class ApiCoSessionServiceImpl implements ApiCoSessionService {
roomRedisInfoDTO
.
setUserId
(
userId
);
roomRedisInfoDTO
.
setControlHolderType
(
session
.
getControlHolderType
());
roomRedisInfoDTO
.
setControlHolderId
(
session
.
getControlHolderId
());
redisUtil
.
setCacheObject
(
RedisEnum
.
ROOM
.
getPrefix
()
+
roomId
,
roomRedisInfoDTO
,
roomRedisInfoDTO
.
setRoomId
(
roomId
);
roomRedisInfoDTO
.
setRoomPwd
(
roomPwd
);
redisUtil
.
setCacheObject
(
RedisEnum
.
ROOM
.
getPrefix
()
+
roomId
+
":"
+
roomPwd
,
roomRedisInfoDTO
,
RedisEnum
.
ROOM
.
getTimeout
(),
RedisEnum
.
ROOM
.
getTimeUnit
());
log
.
info
(
"【创建会话-内部】Redis缓存已设置, key={}"
,
RedisEnum
.
ROOM
.
getPrefix
()
+
roomId
);
...
...
@@ -163,7 +144,95 @@ public class ApiCoSessionServiceImpl implements ApiCoSessionService {
}
/**
* 顾问加入会话(输入共享码加入房间,可以多次加入)
* 创建协同会话
* @param request
* @return
*/
@Override
@Transactional
(
rollbackFor
=
Exception
.
class
)
public
Result
<
CreateResponse
>
create
(
CreateRequest
request
)
{
log
.
info
(
"【创建协同会话】收到创建请求, request={}"
,
request
);
try
{
// 1. 创建会话
CoSession
session
=
createSession
(
request
.
getScope
(),
request
.
getResourceType
(),
request
.
getResourceId
(),
request
.
getResourceInit
(),
request
.
getOwnerId
(),
request
.
getOwnerType
(),
request
.
getUserId
(),
request
.
getToken
()
);
if
(
session
==
null
)
{
log
.
warn
(
"【创建协同会话-生成二维码】创建会话失败"
);
return
Result
.
success
();
}
// 2. 构建房间链接(从配置读取)
String
roomLink
=
roomBaseUrl
+
"?roomId="
+
session
.
getRoomId
()
+
"&pwd="
+
session
.
getRoomPwd
();
log
.
info
(
"【创建协同会话】生成房间链接: {}"
,
roomLink
);
// 3. 生成二维码图片字节数组(PNG格式)
byte
[]
qrCodeBytes
=
QRCodeUtils
.
generateQRCode
(
roomLink
,
300
,
300
);
// 4. 将字节数组转换为 MultipartFile
String
fileName
=
session
.
getCoSessionBizId
()
+
".png"
;
MultipartFile
multipartFile
=
new
ByteArrayMultipartFile
(
qrCodeBytes
,
// 图片字节数组
"file"
,
// 字段名,与 Feign @RequestPart("file") 匹配
fileName
,
// 原始文件名
"image/png"
// 内容类型
);
// 5. 构建 OSS 上传请求参数
ApiUploadFileRequest
ossRequest
=
new
ApiUploadFileRequest
();
ossRequest
.
setObjectBizId
(
session
.
getCoSessionBizId
());
// 必填,使用会话业务ID
ossRequest
.
setObjectType
(
"co_session_qr"
);
// 自定义对象类型
ossRequest
.
setObjectName
(
"协同会话二维码"
);
ossRequest
.
setProjectBizId
(
request
.
getResourceId
());
// 可关联资源ID
ossRequest
.
setTenantBizId
(
request
.
getOwnerId
());
// 可关联所有者
// 6. 调用 Feign 上传
Result
<
ApiUploadResponse
>
uploadResult
=
apiOssFeignClient
.
uploadFileBody
(
multipartFile
,
ossRequest
);
if
(
uploadResult
==
null
||
uploadResult
.
getCode
()
!=
200
||
uploadResult
.
getData
()
==
null
)
{
log
.
error
(
"【创建协同会话】OSS上传失败,result={}"
,
uploadResult
);
throw
new
BusinessException
(
"二维码上传失败:"
+
(
uploadResult
!=
null
?
uploadResult
.
getMsg
()
:
"未知错误"
));
}
// 7. 获取文件访问 URL(假设 ApiUploadResponse 包含 url 字段)
ApiUploadResponse
uploadData
=
uploadResult
.
getData
();
String
roomQrCodeUrl
=
uploadData
.
getUrl
();
// 若字段名为 fileUrl 则对应调整
log
.
info
(
"【创建协同会话】OSS上传成功,文件URL: {}"
,
roomQrCodeUrl
);
//8. 更新会话信息表数据
session
.
setRoomQrCode
(
roomQrCodeUrl
);
session
.
setRoomLink
(
roomLink
);
iCoSessionService
.
saveOrUpdate
(
session
);
//设置房间链接失效时间(用于扫码和链接直接访问,加载页面后调用校验接口判断是否失效)
redisUtil
.
setCacheObject
(
RedisEnum
.
ROOM_LINK
.
getPrefix
()
+
session
.
getRoomId
()
+
":"
+
session
.
getRoomPwd
(),
session
.
getRoomLink
(),
RedisEnum
.
ROOM_LINK
.
getTimeout
(),
RedisEnum
.
ROOM_LINK
.
getTimeUnit
());
//9. 组装响应
CreateResponse
response
=
new
CreateResponse
();
response
.
setRoomId
(
session
.
getRoomId
());
response
.
setRoomPwd
(
session
.
getRoomPwd
());
response
.
setSessionBizId
(
session
.
getCoSessionBizId
());
response
.
setStatus
(
session
.
getStatus
());
response
.
setRoomLink
(
roomLink
);
response
.
setRoomQrCode
(
roomQrCodeUrl
);
log
.
info
(
"【创建协同会话】成功,roomId={}, sessionBizId={}"
,
session
.
getRoomId
(),
session
.
getCoSessionBizId
());
return
Result
.
success
(
response
);
}
catch
(
Exception
e
)
{
log
.
error
(
"【创建协同会话】异常"
,
e
);
throw
new
BusinessException
(
"创建协同会话失败:"
+
e
.
getMessage
());
}
}
/**
* 加入协同会话
*/
@Override
@Transactional
(
rollbackFor
=
Exception
.
class
)
...
...
@@ -171,6 +240,7 @@ public class ApiCoSessionServiceImpl implements ApiCoSessionService {
log
.
info
(
"【加入会话】收到加入请求, request={}"
,
request
);
try
{
CoSession
session
=
joinSession
(
request
.
getRoomId
(),
request
.
getRoomPwd
(),
request
.
getParticipantId
(),
request
.
getParticipantType
()
...
...
@@ -206,19 +276,30 @@ public class ApiCoSessionServiceImpl implements ApiCoSessionService {
}
/**
* 顾问加入会话(内部方法)
* 顾问加入会话
* @param roomId
* @param roomPwd
* @param participantId
* @param participantType
* @return
*/
@Transactional
(
rollbackFor
=
Exception
.
class
)
public
CoSession
joinSession
(
String
roomPwd
,
String
participantId
,
String
participantType
)
{
log
.
info
(
"【加入会话-内部】开始, room
Pwd={}, participantId={}, participantType={}"
,
roomPwd
,
participantId
,
participantType
);
public
CoSession
joinSession
(
String
room
Id
,
String
room
Pwd
,
String
participantId
,
String
participantType
)
{
log
.
info
(
"【加入会话-内部】开始, room
Id={}, roomPwd={}, participantId={}, participantType={}"
,
roomId
,
roomPwd
,
participantId
,
participantType
);
try
{
//校验房间链接是否失效
String
roomLink
=
redisUtil
.
getCacheObject
(
RedisEnum
.
ROOM_LINK
.
getPrefix
()
+
roomId
+
":"
+
roomPwd
);
if
(
StringUtils
.
isBlank
(
roomLink
))
{
throw
new
BusinessException
(
"访问链接已失效,请重新生成"
);
}
LambdaQueryWrapper
<
CoSession
>
wrapper
=
new
LambdaQueryWrapper
<>();
wrapper
.
eq
(
CoSession:
:
getRoomPwd
,
roomPwd
)
wrapper
.
eq
(
CoSession:
:
getRoomId
,
roomId
)
.
eq
(
CoSession:
:
getRoomPwd
,
roomPwd
)
.
last
(
" limit 1 "
);
CoSession
session
=
iCoSessionService
.
getOne
(
wrapper
);
if
(
session
==
null
)
{
log
.
error
(
"【加入会话-内部】未找到会话,room
Pwd={}"
,
roomPwd
);
throw
new
BusinessException
(
"房间
密码(共享码)错误,或客户未发起会话
"
);
log
.
error
(
"【加入会话-内部】未找到会话,room
Id={}, roomPwd={}"
,
roomId
,
roomPwd
);
throw
new
BusinessException
(
"房间
号或者密码错误,无法加入
"
);
}
log
.
info
(
"【加入会话-内部】找到会话, roomId={}, status={}, currentHolder={}:{}"
,
session
.
getRoomId
(),
session
.
getStatus
(),
session
.
getControlHolderType
(),
session
.
getControlHolderId
());
...
...
yd-communication-api/src/main/java/com/yd/communication/api/utils/QRCodeUtils.java
0 → 100644
View file @
63e13557
package
com
.
yd
.
communication
.
api
.
utils
;
import
com.google.zxing.BarcodeFormat
;
import
com.google.zxing.EncodeHintType
;
import
com.google.zxing.client.j2se.MatrixToImageWriter
;
import
com.google.zxing.common.BitMatrix
;
import
com.google.zxing.qrcode.QRCodeWriter
;
import
lombok.extern.slf4j.Slf4j
;
import
java.io.ByteArrayOutputStream
;
import
java.util.HashMap
;
import
java.util.Map
;
@Slf4j
public
class
QRCodeUtils
{
/**
* 生成二维码图片的字节数组(PNG格式)
*
* @param content 二维码内容(如URL)
* @param width 图片宽度(像素)
* @param height 图片高度(像素)
* @return PNG图片的字节数组
*/
public
static
byte
[]
generateQRCode
(
String
content
,
int
width
,
int
height
)
{
try
{
Map
<
EncodeHintType
,
Object
>
hints
=
new
HashMap
<>();
hints
.
put
(
EncodeHintType
.
CHARACTER_SET
,
"UTF-8"
);
hints
.
put
(
EncodeHintType
.
MARGIN
,
1
);
// 边距
QRCodeWriter
writer
=
new
QRCodeWriter
();
BitMatrix
bitMatrix
=
writer
.
encode
(
content
,
BarcodeFormat
.
QR_CODE
,
width
,
height
,
hints
);
ByteArrayOutputStream
baos
=
new
ByteArrayOutputStream
();
MatrixToImageWriter
.
writeToStream
(
bitMatrix
,
"PNG"
,
baos
);
return
baos
.
toByteArray
();
}
catch
(
Exception
e
)
{
log
.
error
(
"生成二维码失败,content={}, width={}, height={}"
,
content
,
width
,
height
,
e
);
throw
new
RuntimeException
(
"生成二维码失败"
,
e
);
}
}
}
\ No newline at end of file
yd-communication-feign/src/main/java/com/yd/communication/feign/client/ApiCoSessionFeignClient.java
View file @
63e13557
...
...
@@ -25,7 +25,7 @@ import org.springframework.web.bind.annotation.*;
public
interface
ApiCoSessionFeignClient
{
/**
*
客户创建协同会话(生成共享码)
*
创建协同会话
*
* @param request 创建会话请求
* @return 会话信息
...
...
yd-communication-feign/src/main/java/com/yd/communication/feign/constant/RedisConstants.java
View file @
63e13557
...
...
@@ -10,4 +10,6 @@ public class RedisConstants {
*/
public
static
final
String
ROOM_KEY_PREFIX
=
"room:"
;
public
static
final
String
ROOM_LINK_KEY_PREFIX
=
"room:link:"
;
}
yd-communication-feign/src/main/java/com/yd/communication/feign/dto/RoomRedisInfoDTO.java
View file @
63e13557
...
...
@@ -13,6 +13,16 @@ public class RoomRedisInfoDTO implements Serializable {
private
static
final
long
serialVersionUID
=
1L
;
/**
* 协同房间号(房间ID)
*/
private
String
roomId
;
/**
* 协同房间密码(输入密码进入房间,协同共享码,进入这个协同房间号的密码)
*/
private
String
roomPwd
;
/**
* 控制权持有者类型:owner(资源所有者类型)/participant(参与者类型)
*/
private
String
controlHolderType
;
...
...
yd-communication-feign/src/main/java/com/yd/communication/feign/enums/RedisEnum.java
View file @
63e13557
...
...
@@ -10,7 +10,9 @@ import java.util.concurrent.TimeUnit;
public
enum
RedisEnum
{
//协同房间缓存信息redis参数
ROOM
(
RedisConstants
.
ROOM_KEY_PREFIX
,
600000000
,
TimeUnit
.
MINUTES
),
ROOM
(
RedisConstants
.
ROOM_KEY_PREFIX
,
120
,
TimeUnit
.
MINUTES
),
//房间链接缓存信息redis参数
ROOM_LINK
(
RedisConstants
.
ROOM_KEY_PREFIX
,
120
,
TimeUnit
.
MINUTES
),
;
//缓存key前缀
...
...
yd-communication-feign/src/main/java/com/yd/communication/feign/request/JoinRequest.java
View file @
63e13557
...
...
@@ -11,12 +11,12 @@ import javax.validation.constraints.NotBlank;
@Data
public
class
JoinRequest
{
//
/**
//
* 协同房间号(房间ID)
//
* 客户创建会话时生成的唯一房间标识
//
* 示例:room_abc12345
//
*/
//
private String roomId;
/**
* 协同房间号(房间ID)
* 客户创建会话时生成的唯一房间标识
* 示例:room_abc12345
*/
private
String
roomId
;
/**
* 协同房间密码(共享码)
...
...
yd-communication-feign/src/main/java/com/yd/communication/feign/response/CreateResponse.java
View file @
63e13557
...
...
@@ -27,4 +27,14 @@ public class CreateResponse {
* 会话状态:0-进行中,1-已结束,2-已超时
*/
private
String
status
;
/**
* 协同房间二维码(扫码进入房间)
*/
private
String
roomQrCode
;
/**
* 协同房间链接(访问链接进入房间)
*/
private
String
roomLink
;
}
\ No newline at end of file
yd-communication-service/pom.xml
View file @
63e13557
...
...
@@ -74,6 +74,15 @@
<version>
${project.version}
</version>
</dependency>
<dependency>
<groupId>
com.google.zxing
</groupId>
<artifactId>
core
</artifactId>
</dependency>
<dependency>
<groupId>
com.google.zxing
</groupId>
<artifactId>
javase
</artifactId>
</dependency>
<!-- <!– 阿里云 Java SDK 核心库 –>-->
<!-- <dependency>-->
<!-- <groupId>com.aliyun</groupId>-->
...
...
yd-communication-service/src/main/java/com/yd/communication/service/model/CoSession.java
View file @
63e13557
...
...
@@ -97,12 +97,24 @@ public class CoSession implements Serializable {
private
String
roomId
;
/**
* 协同房间密码(协同共享码,进入这个协同房间号的密码)
* 协同房间密码(
输入密码进入房间,
协同共享码,进入这个协同房间号的密码)
*/
@TableField
(
"room_pwd"
)
private
String
roomPwd
;
/**
* 协同房间二维码(扫码进入房间)
*/
@TableField
(
"room_qr_code"
)
private
String
roomQrCode
;
/**
* 协同房间链接(访问链接进入房间)
*/
@TableField
(
"room_link"
)
private
String
roomLink
;
/**
* RTC频道前缀,便于区分业务
*/
@TableField
(
"channel_prefix"
)
...
...
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