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
76ebc4a4
Commit
76ebc4a4
authored
Jul 30, 2026
by
zhangxingmin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
push
parent
ed1e4e0a
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
35 changed files
with
1028 additions
and
30 deletions
+1028
-30
.idea/vcs.xml
+4
-0
yd-communication-api/pom.xml
+0
-6
yd-communication-api/src/main/java/com/yd/communication/api/config/WebSocketConfig.java
+14
-0
yd-communication-api/src/main/java/com/yd/communication/api/controller/ApiCoSessionController.java
+78
-0
yd-communication-api/src/main/java/com/yd/communication/api/controller/CoSessionController.java
+0
-18
yd-communication-api/src/main/java/com/yd/communication/api/service/ApiCoSessionService.java
+32
-0
yd-communication-api/src/main/java/com/yd/communication/api/service/impl/ApiCoSessionServiceImpl.java
+0
-0
yd-communication-api/src/main/java/com/yd/communication/api/websocket/CoWebSocketServer.java
+0
-0
yd-communication-feign/src/main/java/com/yd/communication/feign/client/ApiCoSessionFeignClient.java
+69
-0
yd-communication-feign/src/main/java/com/yd/communication/feign/constant/RedisConstants.java
+13
-0
yd-communication-feign/src/main/java/com/yd/communication/feign/dto/RoomRedisInfoDTO.java
+30
-0
yd-communication-feign/src/main/java/com/yd/communication/feign/enums/CoSessionStatusEnum.java
+32
-0
yd-communication-feign/src/main/java/com/yd/communication/feign/enums/ControlHolderTypeEnum.java
+30
-0
yd-communication-feign/src/main/java/com/yd/communication/feign/enums/RedisEnum.java
+42
-0
yd-communication-feign/src/main/java/com/yd/communication/feign/fallback/ApiCoSessionFeignFallbackFactory.java
+53
-0
yd-communication-feign/src/main/java/com/yd/communication/feign/request/CreateRequest.java
+74
-0
yd-communication-feign/src/main/java/com/yd/communication/feign/request/EndSessionRequest.java
+13
-0
yd-communication-feign/src/main/java/com/yd/communication/feign/request/JoinRequest.java
+46
-0
yd-communication-feign/src/main/java/com/yd/communication/feign/request/TransferControlRequest.java
+23
-0
yd-communication-feign/src/main/java/com/yd/communication/feign/response/CommonResponse.java
+21
-0
yd-communication-feign/src/main/java/com/yd/communication/feign/response/CreateResponse.java
+31
-0
yd-communication-feign/src/main/java/com/yd/communication/feign/response/JoinResponse.java
+48
-0
yd-communication-feign/src/main/java/com/yd/communication/feign/response/SessionDetailResponse.java
+107
-0
yd-communication-service/pom.xml
+6
-0
yd-communication-service/src/main/java/com/yd/communication/service/dao/CoSessionMapper.java
+14
-0
yd-communication-service/src/main/java/com/yd/communication/service/model/CoSession.java
+3
-2
yd-communication-service/src/main/java/com/yd/communication/service/model/RecordingTask.java
+3
-3
yd-communication-service/src/main/java/com/yd/communication/service/service/ICoOperationLogService.java
+3
-0
yd-communication-service/src/main/java/com/yd/communication/service/service/ICoSessionService.java
+12
-0
yd-communication-service/src/main/java/com/yd/communication/service/service/IRecordingTaskService.java
+3
-0
yd-communication-service/src/main/java/com/yd/communication/service/service/impl/CoDesensitizationRuleServiceImpl.java
+84
-0
yd-communication-service/src/main/java/com/yd/communication/service/service/impl/CoOperationLogServiceImpl.java
+22
-0
yd-communication-service/src/main/java/com/yd/communication/service/service/impl/CoSessionServiceImpl.java
+31
-1
yd-communication-service/src/main/java/com/yd/communication/service/service/impl/RecordingTaskServiceImpl.java
+71
-0
yd-communication-service/src/main/java/com/yd/communication/service/utils/RandomUtil.java
+16
-0
No files found.
.idea/vcs.xml
View file @
76ebc4a4
...
...
@@ -5,4 +5,7 @@
<list
/>
</option>
</component>
<component
name=
"VcsDirectoryMappings"
>
<mapping
directory=
"$PROJECT_DIR$"
vcs=
"Git"
/>
</component>
</project>
\ No newline at end of file
yd-communication-api/pom.xml
View file @
76ebc4a4
...
...
@@ -29,12 +29,6 @@
<artifactId>
spring-boot-starter-web
</artifactId>
</dependency>
<!-- Spring Boot Starter WebSocket -->
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-websocket
</artifactId>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter
</artifactId>
...
...
yd-communication-api/src/main/java/com/yd/communication/api/config/WebSocketConfig.java
0 → 100644
View file @
76ebc4a4
package
com
.
yd
.
communication
.
api
.
config
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.web.socket.server.standard.ServerEndpointExporter
;
@Configuration
public
class
WebSocketConfig
{
@Bean
public
ServerEndpointExporter
serverEndpointExporter
()
{
return
new
ServerEndpointExporter
();
}
}
\ No newline at end of file
yd-communication-api/src/main/java/com/yd/communication/api/controller/ApiCoSessionController.java
0 → 100644
View file @
76ebc4a4
package
com
.
yd
.
communication
.
api
.
controller
;
import
com.yd.common.result.Result
;
import
com.yd.communication.api.service.ApiCoSessionService
;
import
com.yd.communication.feign.client.ApiCoSessionFeignClient
;
import
com.yd.communication.feign.request.CreateRequest
;
import
com.yd.communication.feign.request.EndSessionRequest
;
import
com.yd.communication.feign.request.JoinRequest
;
import
com.yd.communication.feign.request.TransferControlRequest
;
import
com.yd.communication.feign.response.CommonResponse
;
import
com.yd.communication.feign.response.CreateResponse
;
import
com.yd.communication.feign.response.JoinResponse
;
import
com.yd.communication.feign.response.SessionDetailResponse
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.web.bind.annotation.*
;
import
javax.annotation.Resource
;
/**
* 协同会话信息
*
* @author zxm
* @since 2026-07-28
*/
@RestController
@RequestMapping
(
"/coSession"
)
@Validated
public
class
ApiCoSessionController
implements
ApiCoSessionFeignClient
{
@Resource
private
ApiCoSessionService
apiCoSessionService
;
/**
* 客户创建会话(生成共享码)
* @param request
* @return
*/
public
Result
<
CreateResponse
>
create
(
CreateRequest
request
)
{
return
apiCoSessionService
.
create
(
request
);
}
/**
* 顾问加入会话(输入共享码加入房间,可以多次加入)
* @param request
* @return
*/
@PostMapping
(
"/join"
)
public
Result
<
JoinResponse
>
join
(
JoinRequest
request
)
{
return
apiCoSessionService
.
join
(
request
);
}
/**
* 获取会话详情
* @param bizId
* @return
*/
public
Result
<
SessionDetailResponse
>
get
(
String
bizId
)
{
return
apiCoSessionService
.
get
(
bizId
);
}
/**
* 结束协同会话(关闭共享,仅客户可调用)
* @return
*/
public
Result
<
CommonResponse
>
end
(
EndSessionRequest
request
)
{
return
apiCoSessionService
.
end
(
request
);
}
/**
* 切换控制权(仅参与者(顾问)可调用)
* @param request
* @return
*/
public
Result
<
CommonResponse
>
transferControl
(
TransferControlRequest
request
)
{
return
apiCoSessionService
.
transferControl
(
request
);
}
}
yd-communication-api/src/main/java/com/yd/communication/api/controller/CoSessionController.java
deleted
100644 → 0
View file @
ed1e4e0a
package
com
.
yd
.
communication
.
api
.
controller
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
/**
* <p>
* 协同-会话表(通用) 前端控制器
* </p>
*
* @author zxm
* @since 2026-07-28
*/
@RestController
@RequestMapping
(
"/coSession"
)
public
class
CoSessionController
{
}
yd-communication-api/src/main/java/com/yd/communication/api/service/ApiCoSessionService.java
0 → 100644
View file @
76ebc4a4
package
com
.
yd
.
communication
.
api
.
service
;
import
com.yd.common.result.Result
;
import
com.yd.communication.feign.dto.RoomRedisInfoDTO
;
import
com.yd.communication.feign.request.CreateRequest
;
import
com.yd.communication.feign.request.EndSessionRequest
;
import
com.yd.communication.feign.request.JoinRequest
;
import
com.yd.communication.feign.request.TransferControlRequest
;
import
com.yd.communication.feign.response.CommonResponse
;
import
com.yd.communication.feign.response.CreateResponse
;
import
com.yd.communication.feign.response.JoinResponse
;
import
com.yd.communication.feign.response.SessionDetailResponse
;
import
com.yd.communication.service.model.CoSession
;
public
interface
ApiCoSessionService
{
Result
<
CreateResponse
>
create
(
CreateRequest
request
);
Result
<
JoinResponse
>
join
(
JoinRequest
request
);
Result
<
SessionDetailResponse
>
get
(
String
bizId
);
Result
<
CommonResponse
>
end
(
EndSessionRequest
request
);
Result
<
CommonResponse
>
transferControl
(
TransferControlRequest
request
);
RoomRedisInfoDTO
getCurrentController
(
String
roomId
);
void
updateCurrentPage
(
String
roomId
,
String
newPageJson
,
String
operatorId
);
CoSession
getByRoomId
(
String
roomId
);
}
yd-communication-api/src/main/java/com/yd/communication/api/service/impl/ApiCoSessionServiceImpl.java
0 → 100644
View file @
76ebc4a4
This diff is collapsed.
Click to expand it.
yd-communication-api/src/main/java/com/yd/communication/api/websocket/CoWebSocketServer.java
0 → 100644
View file @
76ebc4a4
This diff is collapsed.
Click to expand it.
yd-communication-feign/src/main/java/com/yd/communication/feign/client/ApiCoSessionFeignClient.java
0 → 100644
View file @
76ebc4a4
package
com
.
yd
.
communication
.
feign
.
client
;
import
com.yd.common.result.Result
;
import
com.yd.communication.feign.fallback.ApiCoSessionFeignFallbackFactory
;
import
com.yd.communication.feign.request.CreateRequest
;
import
com.yd.communication.feign.request.EndSessionRequest
;
import
com.yd.communication.feign.request.JoinRequest
;
import
com.yd.communication.feign.request.TransferControlRequest
;
import
com.yd.communication.feign.response.CommonResponse
;
import
com.yd.communication.feign.response.CreateResponse
;
import
com.yd.communication.feign.response.JoinResponse
;
import
com.yd.communication.feign.response.SessionDetailResponse
;
import
org.springframework.cloud.openfeign.FeignClient
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.web.bind.annotation.*
;
/**
* 通信服务-协同会话信息 Feign 客户端
*
* @author zxm
* @date 2026-07-28
*/
@FeignClient
(
name
=
"yd-communication-api"
,
path
=
"/communication/api/coSession"
,
fallbackFactory
=
ApiCoSessionFeignFallbackFactory
.
class
)
public
interface
ApiCoSessionFeignClient
{
/**
* 客户创建协同会话(生成共享码)
*
* @param request 创建会话请求
* @return 会话信息
*/
@PostMapping
(
"/create"
)
Result
<
CreateResponse
>
create
(
@Validated
@RequestBody
CreateRequest
request
);
/**
* 顾问加入协同会话(输入共享码)
*
* @param request 加入会话请求
* @return 会话详情
*/
@PostMapping
(
"/join"
)
Result
<
JoinResponse
>
join
(
@Validated
@RequestBody
JoinRequest
request
);
/**
* 获取协同会话详情
*
* @param bizId 会话业务ID
* @return 完整会话信息
*/
@GetMapping
(
"/{bizId}"
)
Result
<
SessionDetailResponse
>
get
(
@PathVariable
(
"bizId"
)
String
bizId
);
/**
* 结束协同会话(关闭共享,仅客户可调用)
*
*/
@PostMapping
(
"/end"
)
Result
<
CommonResponse
>
end
(
@Validated
@RequestBody
EndSessionRequest
request
);
/**
* 切换控制权(仅参与者(顾问)可调用)
* @param request
* @return
*/
@PostMapping
(
"/control/transfer"
)
Result
<
CommonResponse
>
transferControl
(
@Validated
@RequestBody
TransferControlRequest
request
);
}
\ No newline at end of file
yd-communication-feign/src/main/java/com/yd/communication/feign/constant/RedisConstants.java
0 → 100644
View file @
76ebc4a4
package
com
.
yd
.
communication
.
feign
.
constant
;
/**
* redis的key前缀常量
*/
public
class
RedisConstants
{
/**
* 协同房间缓存信息redis前缀
*/
public
static
final
String
ROOM_KEY_PREFIX
=
"room:"
;
}
yd-communication-feign/src/main/java/com/yd/communication/feign/dto/RoomRedisInfoDTO.java
0 → 100644
View file @
76ebc4a4
package
com
.
yd
.
communication
.
feign
.
dto
;
import
lombok.Data
;
/**
* 存储当前房间内的一些缓存字段信息
*/
@Data
public
class
RoomRedisInfoDTO
{
/**
* 控制权持有者类型:owner(资源所有者类型)/participant(参与者类型)
*/
private
String
controlHolderType
;
/**
* 控制权持有者ID(具体人的ID)
*/
private
String
controlHolderId
;
/**
* 资源所有者的登录用户ID
*/
private
String
userId
;
/**
* 资源所有者的登录token信息
*/
private
String
token
;
}
yd-communication-feign/src/main/java/com/yd/communication/feign/enums/CoSessionStatusEnum.java
0 → 100644
View file @
76ebc4a4
package
com
.
yd
.
communication
.
feign
.
enums
;
/**
* 协同会话状态枚举
*/
public
enum
CoSessionStatusEnum
{
DKS
(
"待开始"
,
"1"
),
JXZ
(
"进行中"
,
"2"
),
YJS
(
"已结束"
,
"3"
),
YCS
(
"已超时"
,
"4"
),
;
//字典项标签(名称)
private
String
itemLabel
;
//字典项值
private
String
itemValue
;
//构造函数
CoSessionStatusEnum
(
String
itemLabel
,
String
itemValue
)
{
this
.
itemLabel
=
itemLabel
;
this
.
itemValue
=
itemValue
;
}
public
String
getItemLabel
()
{
return
itemLabel
;
}
public
String
getItemValue
()
{
return
itemValue
;
}
}
yd-communication-feign/src/main/java/com/yd/communication/feign/enums/ControlHolderTypeEnum.java
0 → 100644
View file @
76ebc4a4
package
com
.
yd
.
communication
.
feign
.
enums
;
/**
* 控制权持有者类型枚举
*/
public
enum
ControlHolderTypeEnum
{
OWNER
(
"资源所有者类型"
,
"owner"
),
PARTICIPANT
(
"参与者类型"
,
"participant"
),
;
//字典项标签(名称)
private
String
itemLabel
;
//字典项值
private
String
itemValue
;
//构造函数
ControlHolderTypeEnum
(
String
itemLabel
,
String
itemValue
)
{
this
.
itemLabel
=
itemLabel
;
this
.
itemValue
=
itemValue
;
}
public
String
getItemLabel
()
{
return
itemLabel
;
}
public
String
getItemValue
()
{
return
itemValue
;
}
}
yd-communication-feign/src/main/java/com/yd/communication/feign/enums/RedisEnum.java
0 → 100644
View file @
76ebc4a4
package
com
.
yd
.
communication
.
feign
.
enums
;
import
com.yd.communication.feign.constant.RedisConstants
;
import
java.util.concurrent.TimeUnit
;
/**
* redis枚举
*/
public
enum
RedisEnum
{
//协同房间缓存信息redis参数
ROOM
(
RedisConstants
.
ROOM_KEY_PREFIX
,
600000000
,
TimeUnit
.
MINUTES
),
;
//缓存key前缀
private
String
prefix
;
//缓存过期时长
private
Integer
timeout
;
//缓存过期时长单位
private
TimeUnit
timeUnit
;
RedisEnum
(
String
prefix
,
Integer
timeout
,
TimeUnit
timeUnit
)
{
this
.
prefix
=
prefix
;
this
.
timeout
=
timeout
;
this
.
timeUnit
=
timeUnit
;
}
public
String
getPrefix
()
{
return
prefix
;
}
public
Integer
getTimeout
()
{
return
timeout
;
}
public
TimeUnit
getTimeUnit
()
{
return
timeUnit
;
}
}
yd-communication-feign/src/main/java/com/yd/communication/feign/fallback/ApiCoSessionFeignFallbackFactory.java
0 → 100644
View file @
76ebc4a4
package
com
.
yd
.
communication
.
feign
.
fallback
;
import
com.yd.common.result.Result
;
import
com.yd.communication.feign.client.ApiCoSessionFeignClient
;
import
com.yd.communication.feign.request.CreateRequest
;
import
com.yd.communication.feign.request.EndSessionRequest
;
import
com.yd.communication.feign.request.JoinRequest
;
import
com.yd.communication.feign.request.TransferControlRequest
;
import
com.yd.communication.feign.response.CommonResponse
;
import
com.yd.communication.feign.response.CreateResponse
;
import
com.yd.communication.feign.response.JoinResponse
;
import
com.yd.communication.feign.response.SessionDetailResponse
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.cloud.openfeign.FallbackFactory
;
import
org.springframework.stereotype.Component
;
/**
* 通信服务-协同会话信息Feign降级处理
*/
@Slf4j
@Component
public
class
ApiCoSessionFeignFallbackFactory
implements
FallbackFactory
<
ApiCoSessionFeignClient
>
{
@Override
public
ApiCoSessionFeignClient
create
(
Throwable
cause
)
{
return
new
ApiCoSessionFeignClient
()
{
@Override
public
Result
<
CreateResponse
>
create
(
CreateRequest
request
)
{
return
null
;
}
@Override
public
Result
<
JoinResponse
>
join
(
JoinRequest
request
)
{
return
null
;
}
@Override
public
Result
<
SessionDetailResponse
>
get
(
String
bizId
)
{
return
null
;
}
@Override
public
Result
<
CommonResponse
>
end
(
EndSessionRequest
request
)
{
return
null
;
}
@Override
public
Result
<
CommonResponse
>
transferControl
(
TransferControlRequest
request
)
{
return
null
;
}
};
}
}
yd-communication-feign/src/main/java/com/yd/communication/feign/request/CreateRequest.java
0 → 100644
View file @
76ebc4a4
package
com
.
yd
.
communication
.
feign
.
request
;
import
lombok.Data
;
import
javax.validation.constraints.NotBlank
;
/**
* 创建协同会话请求对象
* 客户调用此接口生成共享码,开启协同讲解
*/
@Data
public
class
CreateRequest
{
/**
* 协同作用域
* single: 单个资源(如单份报告、资讯)
* global: 全局协同(如小程序全局协同,切换页面自动跟随)
*/
@NotBlank
(
message
=
"协同作用域不能为空"
)
private
String
scope
;
/**
* 资源类型
* 用于区分不同的业务资源类型
* 可选值:report(报告)、news(资讯)、mini_program(小程序)等
*/
@NotBlank
(
message
=
"资源类型不能为空"
)
private
String
resourceType
;
/**
* 资源业务ID
* 具体资源的唯一标识
* 如:report-报告ID、news-资讯ID、mini_program-小程序应用标识
*/
@NotBlank
(
message
=
"资源业务ID不能为空"
)
private
String
resourceId
;
/**
* 资源初始化JSON串
* 创建会话时记录当前所在页面的完整信息,后续不做修改,用于历史追溯
* 示例:{"url":"https://mini.xxx.com/pages/index/index?userId=xxx"}
*/
@NotBlank
(
message
=
"资源初始化JSON串不能为空"
)
private
String
resourceInit
;
/**
* 资源所有者ID(即客户ID)
* 报告/资源的归属人,通常为发起协同的客户
*/
@NotBlank
(
message
=
"资源所有者ID不能为空"
)
private
String
ownerId
;
/**
* 资源所有者类型
* 默认:customer(客户)
* 可扩展:member(会员)、user(普通用户)等
*/
@NotBlank
(
message
=
"资源所有者类型不能为空"
)
private
String
ownerType
;
/**
* 资源所有者的登录用户ID
*/
@NotBlank
(
message
=
"资源所有者的登录用户ID不能为空"
)
private
String
userId
;
/**
* 资源所有者的登录token信息
*/
@NotBlank
(
message
=
"资源所有者的登录token信息不能为空"
)
private
String
token
;
}
\ No newline at end of file
yd-communication-feign/src/main/java/com/yd/communication/feign/request/EndSessionRequest.java
0 → 100644
View file @
76ebc4a4
package
com
.
yd
.
communication
.
feign
.
request
;
import
lombok.Data
;
@Data
public
class
EndSessionRequest
{
/**
* 房间号不能为空
*/
private
String
roomId
;
}
yd-communication-feign/src/main/java/com/yd/communication/feign/request/JoinRequest.java
0 → 100644
View file @
76ebc4a4
package
com
.
yd
.
communication
.
feign
.
request
;
import
lombok.Data
;
import
javax.validation.constraints.NotBlank
;
/**
* 加入协同会话请求对象
* 顾问输入房间号和共享码加入协同
*/
@Data
public
class
JoinRequest
{
// /**
// * 协同房间号(房间ID)
// * 客户创建会话时生成的唯一房间标识
// * 示例:room_abc12345
// */
// private String roomId;
/**
* 协同房间密码(共享码)
* 客户生成共享会话时返回的6位数字密码
* 顾问需要输入此密码才能加入协同
*/
@NotBlank
(
message
=
"房间密码不能为空"
)
private
String
roomPwd
;
/**
* 参与者ID(即顾问ID)
* 加入协同的顾问/专家的唯一标识
*/
@NotBlank
(
message
=
"参与者ID不能为空"
)
private
String
participantId
;
/**
* 参与者类型
* 默认:consultant(顾问)
* 可扩展:expert(专家)、trainer(培训师)等
*/
@NotBlank
(
message
=
"参与者类型不能为空"
)
private
String
participantType
;
}
\ No newline at end of file
yd-communication-feign/src/main/java/com/yd/communication/feign/request/TransferControlRequest.java
0 → 100644
View file @
76ebc4a4
package
com
.
yd
.
communication
.
feign
.
request
;
import
lombok.Data
;
import
javax.validation.constraints.NotBlank
;
import
javax.validation.constraints.NotNull
;
@Data
public
class
TransferControlRequest
{
/**
* 操作类型:1-开启客户操作 2-关闭客户操作
*/
@NotNull
(
message
=
"操作类型不能为空"
)
private
Integer
oprType
;
/**
* 房间号
*/
@NotBlank
(
message
=
"房间号不能为空"
)
private
String
roomId
;
}
yd-communication-feign/src/main/java/com/yd/communication/feign/response/CommonResponse.java
0 → 100644
View file @
76ebc4a4
package
com
.
yd
.
communication
.
feign
.
response
;
import
lombok.AllArgsConstructor
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
/**
* 通用操作响应对象
* 用于结束会话、切换控制权等无需返回业务数据的操作
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public
class
CommonResponse
{
/**
* 操作结果消息
*/
private
String
message
;
}
\ No newline at end of file
yd-communication-feign/src/main/java/com/yd/communication/feign/response/CreateResponse.java
0 → 100644
View file @
76ebc4a4
package
com
.
yd
.
communication
.
feign
.
response
;
import
lombok.Data
;
/**
* 创建协同会话响应对象
*/
@Data
public
class
CreateResponse
{
/**
* 会话唯一业务ID
*/
private
String
sessionBizId
;
/**
* 房间号
*/
private
String
roomId
;
/**
* 共享码(6位数字)
*/
private
String
roomPwd
;
/**
* 会话状态:0-进行中,1-已结束,2-已超时
*/
private
String
status
;
}
\ No newline at end of file
yd-communication-feign/src/main/java/com/yd/communication/feign/response/JoinResponse.java
0 → 100644
View file @
76ebc4a4
package
com
.
yd
.
communication
.
feign
.
response
;
import
lombok.Data
;
import
javax.validation.constraints.NotBlank
;
/**
* 加入协同会话响应对象
*/
@Data
public
class
JoinResponse
{
/**
* 会话唯一业务ID
*/
private
String
sessionBizId
;
/**
* 房间号
*/
private
String
roomId
;
/**
* 资源初始化JSON(用于初始加载)
*/
private
String
resourceInit
;
/**
* 控制权持有者类型:owner-客户,participant-顾问
*/
private
String
controlHolderType
;
/**
* 控制权持有者ID
*/
private
String
controlHolderId
;
/**
* 资源所有者的登录用户ID
*/
private
String
userId
;
/**
* 资源所有者的登录token信息
*/
private
String
token
;
}
\ No newline at end of file
yd-communication-feign/src/main/java/com/yd/communication/feign/response/SessionDetailResponse.java
0 → 100644
View file @
76ebc4a4
package
com
.
yd
.
communication
.
feign
.
response
;
import
lombok.Data
;
import
java.time.LocalDateTime
;
/**
* 协同会话详情响应对象
*/
@Data
public
class
SessionDetailResponse
{
/**
* 数据库主键
*/
private
Long
id
;
/**
* 协同-会话表唯一业务ID
*/
private
String
coSessionBizId
;
/**
* 会话编号
*/
private
String
coSessionNo
;
/**
* 协同作用域:single-单资源,global-全域
*/
private
String
scope
;
/**
* 资源类型:report/news/mini_program
*/
private
String
resourceType
;
/**
* 资源业务ID(如报告ID、小程序标识等)
*/
private
String
resourceId
;
/**
* 资源初始化JSON(创建时页面快照)
*/
private
String
resourceInit
;
/**
* 所有者类型:customer-客户
*/
private
String
ownerType
;
/**
* 所有者ID(客户ID)
*/
private
String
ownerId
;
/**
* 参与者类型:consultant-顾问
*/
private
String
participantType
;
/**
* 参与者ID(顾问ID)
*/
private
String
participantId
;
/**
* 房间号
*/
private
String
roomId
;
/**
* 控制权持有者类型:owner-客户,participant-顾问
*/
private
String
controlHolderType
;
/**
* 控制权持有者ID
*/
private
String
controlHolderId
;
/**
* 会话状态:0-进行中,1-已结束,2-已超时
*/
private
String
status
;
/**
* 会话开始时间
*/
private
LocalDateTime
startTime
;
/**
* 会话结束时间
*/
private
LocalDateTime
endTime
;
/**
* 当前页面JSON(实时更新)
*/
private
String
currentPage
;
/**
* 页面访问历史轨迹(JSON数组)
*/
private
String
pageHistory
;
}
\ No newline at end of file
yd-communication-service/pom.xml
View file @
76ebc4a4
...
...
@@ -50,6 +50,12 @@
<artifactId>
freemarker
</artifactId>
</dependency>
<!-- Spring Boot Starter WebSocket -->
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-websocket
</artifactId>
</dependency>
<dependency>
<groupId>
com.yd
</groupId>
<artifactId>
yd-communication-feign
</artifactId>
...
...
yd-communication-service/src/main/java/com/yd/communication/service/dao/CoSessionMapper.java
View file @
76ebc4a4
...
...
@@ -2,6 +2,10 @@ package com.yd.communication.service.dao;
import
com.yd.communication.service.model.CoSession
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
import
org.apache.ibatis.annotations.Param
;
import
org.apache.ibatis.annotations.Update
;
import
java.time.LocalDateTime
;
/**
* <p>
...
...
@@ -13,4 +17,14 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
*/
public
interface
CoSessionMapper
extends
BaseMapper
<
CoSession
>
{
@Update
(
"UPDATE co_session SET status = #{status}, end_time = #{endTime} WHERE room_id = #{roomId}"
)
int
updateStatusAndEndTimeByRoomId
(
@Param
(
"roomId"
)
String
roomId
,
@Param
(
"status"
)
Integer
status
,
@Param
(
"endTime"
)
LocalDateTime
endTime
);
@Update
(
"UPDATE co_session SET current_page = #{currentPage}, page_history = #{pageHistory}, updater_id = #{updaterId} WHERE room_id = #{roomId}"
)
int
updateCurrentPageAndHistory
(
@Param
(
"roomId"
)
String
roomId
,
@Param
(
"currentPage"
)
String
currentPage
,
@Param
(
"pageHistory"
)
String
pageHistory
,
@Param
(
"updaterId"
)
String
updaterId
);
}
yd-communication-service/src/main/java/com/yd/communication/service/model/CoSession.java
View file @
76ebc4a4
...
...
@@ -121,10 +121,10 @@ public class CoSession implements Serializable {
private
String
controlHolderId
;
/**
*
0-进行中,1-已结束,2
-已超时
*
1-待开始,2-进行中,3-已结束,4
-已超时
*/
@TableField
(
"status"
)
private
Integer
status
;
private
String
status
;
/**
* 开始时间
...
...
@@ -185,4 +185,5 @@ public class CoSession implements Serializable {
*/
@TableField
(
"update_time"
)
private
LocalDateTime
updateTime
;
}
yd-communication-service/src/main/java/com/yd/communication/service/model/RecordingTask.java
View file @
76ebc4a4
...
...
@@ -49,7 +49,7 @@ public class RecordingTask implements Serializable {
private
String
taskId
;
/**
* 业务类型:co
-
session/meeting
* 业务类型:co
_
session/meeting
*/
@TableField
(
"biz_type"
)
private
String
bizType
;
...
...
@@ -85,10 +85,10 @@ public class RecordingTask implements Serializable {
private
String
layout
;
/**
*
0-初始化,1-录制中,2-已停止,3-失败,4
-已归档
*
1-初始化,2-录制中,3-已停止,4-失败,5
-已归档
*/
@TableField
(
"status"
)
private
Integer
status
;
private
String
status
;
/**
* 录制开始时间
...
...
yd-communication-service/src/main/java/com/yd/communication/service/service/ICoOperationLogService.java
View file @
76ebc4a4
...
...
@@ -13,4 +13,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/
public
interface
ICoOperationLogService
extends
IService
<
CoOperationLog
>
{
void
log
(
String
bizId
,
String
operatorId
,
String
operatorType
,
String
operatorName
,
String
action
,
String
content
,
String
deviceNumber
,
String
ip
);
}
yd-communication-service/src/main/java/com/yd/communication/service/service/ICoSessionService.java
View file @
76ebc4a4
...
...
@@ -2,6 +2,7 @@ package com.yd.communication.service.service;
import
com.yd.communication.service.model.CoSession
;
import
com.baomidou.mybatisplus.extension.service.IService
;
import
org.springframework.transaction.annotation.Transactional
;
/**
* <p>
...
...
@@ -13,4 +14,15 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/
public
interface
ICoSessionService
extends
IService
<
CoSession
>
{
/**
* 根据房间ID获取会话(WebSocket 使用)
*/
CoSession
getByRoomId
(
String
roomId
);
/**
* 根据业务ID获取会话
*/
CoSession
getByBizId
(
String
bizId
);
int
updateCurrentPageAndHistory
(
String
roomId
,
String
currentPage
,
String
pageHistory
,
String
updaterId
);
}
yd-communication-service/src/main/java/com/yd/communication/service/service/IRecordingTaskService.java
View file @
76ebc4a4
...
...
@@ -13,4 +13,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/
public
interface
IRecordingTaskService
extends
IService
<
RecordingTask
>
{
String
startRecording
(
String
bizId
,
String
roomId
);
void
stopRecording
(
String
taskId
);
}
yd-communication-service/src/main/java/com/yd/communication/service/service/impl/CoDesensitizationRuleServiceImpl.java
View file @
76ebc4a4
package
com
.
yd
.
communication
.
service
.
service
.
impl
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.fasterxml.jackson.databind.JsonNode
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.yd.communication.service.model.CoDesensitizationRule
;
import
com.yd.communication.service.dao.CoDesensitizationRuleMapper
;
import
com.yd.communication.service.service.ICoDesensitizationRuleService
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
javax.annotation.Resource
;
import
java.util.List
;
/**
* <p>
* 协同-脱敏设置表(通用) 服务实现类
...
...
@@ -14,7 +22,83 @@ import org.springframework.stereotype.Service;
* @author zxm
* @since 2026-07-28
*/
@Slf4j
@Service
public
class
CoDesensitizationRuleServiceImpl
extends
ServiceImpl
<
CoDesensitizationRuleMapper
,
CoDesensitizationRule
>
implements
ICoDesensitizationRuleService
{
@Resource
private
CoDesensitizationRuleMapper
ruleMapper
;
private
final
ObjectMapper
objectMapper
=
new
ObjectMapper
();
public
String
applyDesensitization
(
String
rawData
,
String
resourceType
,
String
resourceId
)
{
// 获取规则(先特定资源,再默认)
LambdaQueryWrapper
<
CoDesensitizationRule
>
wrapper
=
new
LambdaQueryWrapper
<>();
wrapper
.
eq
(
CoDesensitizationRule:
:
getResourceType
,
resourceType
)
.
eq
(
CoDesensitizationRule:
:
getEnabled
,
1
)
.
orderByAsc
(
CoDesensitizationRule:
:
getSortOrder
);
List
<
CoDesensitizationRule
>
rules
;
// 先查特定资源
wrapper
.
eq
(
CoDesensitizationRule:
:
getResourceId
,
resourceId
);
rules
=
ruleMapper
.
selectList
(
wrapper
);
if
(
rules
.
isEmpty
())
{
// 查默认规则
wrapper
.
clear
();
wrapper
.
eq
(
CoDesensitizationRule:
:
getResourceType
,
resourceType
)
.
eq
(
CoDesensitizationRule:
:
getIsDefault
,
1
)
.
eq
(
CoDesensitizationRule:
:
getEnabled
,
1
)
.
orderByAsc
(
CoDesensitizationRule:
:
getSortOrder
);
rules
=
ruleMapper
.
selectList
(
wrapper
);
}
if
(
rules
.
isEmpty
())
{
return
rawData
;
}
try
{
JsonNode
root
=
objectMapper
.
readTree
(
rawData
);
for
(
CoDesensitizationRule
rule
:
rules
)
{
String
fieldPath
=
rule
.
getFieldPath
();
// 简单处理:假设路径是$.xxx,直接取字段
String
fieldName
=
fieldPath
.
replace
(
"$."
,
""
);
if
(
root
.
has
(
fieldName
))
{
String
original
=
root
.
get
(
fieldName
).
asText
();
String
masked
=
maskValue
(
original
,
rule
.
getMaskType
(),
rule
.
getMaskConfig
());
// 由于JsonNode不可变,简单返回,生产需构建新节点
}
}
return
objectMapper
.
writeValueAsString
(
root
);
}
catch
(
Exception
e
)
{
log
.
error
(
"脱敏失败"
,
e
);
return
rawData
;
}
}
private
String
maskValue
(
String
original
,
String
maskType
,
String
maskConfig
)
{
try
{
JsonNode
config
=
objectMapper
.
readTree
(
maskConfig
!=
null
?
maskConfig
:
"{}"
);
int
prefix
=
config
.
has
(
"prefix"
)
?
config
.
get
(
"prefix"
).
asInt
()
:
0
;
int
suffix
=
config
.
has
(
"suffix"
)
?
config
.
get
(
"suffix"
).
asInt
()
:
0
;
String
replaceChar
=
config
.
has
(
"replace_char"
)
?
config
.
get
(
"replace_char"
).
asText
()
:
"*"
;
switch
(
maskType
)
{
case
"mask"
:
case
"partial"
:
if
(
original
.
length
()
<=
prefix
+
suffix
)
return
original
;
int
middle
=
original
.
length
()
-
prefix
-
suffix
;
return
original
.
substring
(
0
,
prefix
)
+
// replaceChar.repeat(middle) +
original
.
substring
(
original
.
length
()
-
suffix
);
case
"hide"
:
return
"****"
;
case
"replace"
:
return
config
.
has
(
"replace_char"
)
?
config
.
get
(
"replace_char"
).
asText
()
:
"***"
;
default
:
return
original
;
}
}
catch
(
Exception
e
)
{
return
original
;
}
}
}
yd-communication-service/src/main/java/com/yd/communication/service/service/impl/CoOperationLogServiceImpl.java
View file @
76ebc4a4
...
...
@@ -4,6 +4,7 @@ import com.yd.communication.service.model.CoOperationLog;
import
com.yd.communication.service.dao.CoOperationLogMapper
;
import
com.yd.communication.service.service.ICoOperationLogService
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.stereotype.Service
;
/**
...
...
@@ -14,7 +15,28 @@ import org.springframework.stereotype.Service;
* @author zxm
* @since 2026-07-28
*/
@Slf4j
@Service
public
class
CoOperationLogServiceImpl
extends
ServiceImpl
<
CoOperationLogMapper
,
CoOperationLog
>
implements
ICoOperationLogService
{
@Override
public
void
log
(
String
bizId
,
String
operatorId
,
String
operatorType
,
String
operatorName
,
String
action
,
String
content
,
String
deviceNumber
,
String
ip
)
{
CoOperationLog
log
=
new
CoOperationLog
();
log
.
setBizType
(
"co_session"
);
log
.
setBizId
(
bizId
);
log
.
setOperatorId
(
operatorId
);
log
.
setOperatorType
(
operatorType
);
log
.
setOperatorName
(
operatorName
);
log
.
setAction
(
action
);
log
.
setActionCategory
(
"control"
);
log
.
setContent
(
content
);
log
.
setOperatorDeviceNumber
(
deviceNumber
);
log
.
setOperatorIp
(
ip
);
log
.
setCreatorId
(
operatorId
);
log
.
setUpdaterId
(
operatorId
);
this
.
save
(
log
);
}
}
yd-communication-service/src/main/java/com/yd/communication/service/service/impl/CoSessionServiceImpl.java
View file @
76ebc4a4
...
...
@@ -2,9 +2,11 @@ package com.yd.communication.service.service.impl;
import
com.yd.communication.service.model.CoSession
;
import
com.yd.communication.service.dao.CoSessionMapper
;
import
com.yd.communication.service.service.ICoSessionService
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.yd.communication.service.service.ICoSessionService
;
import
org.springframework.stereotype.Service
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
lombok.extern.slf4j.Slf4j
;
/**
* <p>
...
...
@@ -15,6 +17,34 @@ import org.springframework.stereotype.Service;
* @since 2026-07-28
*/
@Service
@Slf4j
public
class
CoSessionServiceImpl
extends
ServiceImpl
<
CoSessionMapper
,
CoSession
>
implements
ICoSessionService
{
/**
* 根据房间ID获取会话(WebSocket 使用)
*/
@Override
public
CoSession
getByRoomId
(
String
roomId
)
{
LambdaQueryWrapper
<
CoSession
>
wrapper
=
new
LambdaQueryWrapper
<>();
wrapper
.
eq
(
CoSession:
:
getRoomId
,
roomId
)
.
eq
(
CoSession:
:
getIsDeleted
,
0
);
return
this
.
getOne
(
wrapper
);
}
/**
* 根据业务ID获取会话
*/
@Override
public
CoSession
getByBizId
(
String
bizId
)
{
return
this
.
lambdaQuery
()
.
eq
(
CoSession:
:
getCoSessionBizId
,
bizId
)
.
last
(
" limit 1 "
)
.
one
();
}
@Override
public
int
updateCurrentPageAndHistory
(
String
roomId
,
String
currentPage
,
String
pageHistory
,
String
updaterId
){
return
baseMapper
.
updateCurrentPageAndHistory
(
roomId
,
currentPage
,
pageHistory
,
updaterId
);
}
}
yd-communication-service/src/main/java/com/yd/communication/service/service/impl/RecordingTaskServiceImpl.java
View file @
76ebc4a4
package
com
.
yd
.
communication
.
service
.
service
.
impl
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.yd.common.enums.CommonEnum
;
import
com.yd.common.utils.RandomStringGenerator
;
import
com.yd.communication.service.model.RecordingTask
;
import
com.yd.communication.service.dao.RecordingTaskMapper
;
import
com.yd.communication.service.service.IRecordingTaskService
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.stereotype.Service
;
import
java.time.LocalDateTime
;
import
java.util.UUID
;
/**
* <p>
...
...
@@ -14,7 +20,72 @@ import org.springframework.stereotype.Service;
* @author zxm
* @since 2026-07-28
*/
@Slf4j
@Service
public
class
RecordingTaskServiceImpl
extends
ServiceImpl
<
RecordingTaskMapper
,
RecordingTask
>
implements
IRecordingTaskService
{
/**
* 初始化录制信息(协同生成共享码的时候就初始化信息)
* @param bizId
* @param roomId
* @return
*/
@Override
public
String
startRecording
(
String
bizId
,
String
roomId
)
{
//任务ID
String
taskId
=
"agora_"
+
System
.
currentTimeMillis
();
RecordingTask
task
=
new
RecordingTask
();
//录制任务表唯一业务ID
task
.
setRecordingTaskBizId
(
RandomStringGenerator
.
generateBizId16
(
CommonEnum
.
UID_TYPE_RECORDING_TASK
.
getCode
()));
//任务编号
task
.
setTaskNo
(
"R"
+
System
.
currentTimeMillis
());
task
.
setTaskId
(
taskId
);
//关联的任务类型: 协同会话
task
.
setBizType
(
"co_session"
);
//关联的任务类型表的ID: 协同会话表唯一业务ID
task
.
setBizId
(
bizId
);
//房间号
task
.
setRoomId
(
roomId
);
//RTC频道名
task
.
setChannel
(
"channel_"
+
roomId
);
//录制模式
task
.
setRecordingMode
(
"mix"
);
//布局
task
.
setLayout
(
"grid"
);
//1-初始化
task
.
setStatus
(
"1"
);
task
.
setStartTime
(
LocalDateTime
.
now
());
task
.
setCreatorId
(
"system"
);
this
.
save
(
task
);
log
.
info
(
"启动录制成功, taskId={}, roomId={}"
,
taskId
,
roomId
);
return
taskId
;
}
@Override
public
void
stopRecording
(
String
taskId
)
{
LambdaQueryWrapper
<
RecordingTask
>
wrapper
=
new
LambdaQueryWrapper
<>();
wrapper
.
eq
(
RecordingTask:
:
getTaskId
,
taskId
);
RecordingTask
task
=
this
.
getOne
(
wrapper
);
if
(
task
==
null
)
{
throw
new
RuntimeException
(
"录制任务不存在"
);
}
// 模拟停止录制
task
.
setStatus
(
"3"
);
task
.
setStopTime
(
LocalDateTime
.
now
());
task
.
setFileUrl
(
"https://oss.example.com/recordings/"
+
taskId
+
".mp4"
);
task
.
setFileDuration
(
120
);
task
.
setFileSize
(
1024000L
);
task
.
setFileMd5
(
UUID
.
randomUUID
().
toString
().
substring
(
0
,
32
));
task
.
setFileFormat
(
"mp4"
);
task
.
setStorageType
(
"oss"
);
task
.
setStorageBucket
(
"coordination-recordings"
);
task
.
setStoragePath
(
"/recordings/"
+
taskId
+
".mp4"
);
task
.
setUpdaterId
(
"system"
);
this
.
updateById
(
task
);
log
.
info
(
"停止录制成功, taskId={}"
,
taskId
);
}
}
yd-communication-service/src/main/java/com/yd/communication/service/utils/RandomUtil.java
0 → 100644
View file @
76ebc4a4
package
com
.
yd
.
communication
.
service
.
utils
;
import
java.security.SecureRandom
;
public
class
RandomUtil
{
private
static
final
SecureRandom
random
=
new
SecureRandom
();
public
static
String
generateNumericCode
(
int
length
)
{
StringBuilder
sb
=
new
StringBuilder
();
for
(
int
i
=
0
;
i
<
length
;
i
++)
{
sb
.
append
(
random
.
nextInt
(
10
));
}
return
sb
.
toString
();
}
}
\ 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