Compare commits
14 Commits
5fcacbcb14
...
e634c4c789
| Author | SHA1 | Date |
|---|---|---|
|
|
e634c4c789 | |
|
|
5a04831a98 | |
|
|
4b60e9de10 | |
|
|
62111aefd4 | |
|
|
a51cfc23ce | |
|
|
a469439862 | |
|
|
f9d94b2e60 | |
|
|
d2c44ed0e2 | |
|
|
f08e40d051 | |
|
|
58c70d57bc | |
|
|
8cab92fd5c | |
|
|
ef0782b34a | |
|
|
691fe40131 | |
|
|
5612e79911 |
File diff suppressed because it is too large
Load Diff
|
|
@ -3,17 +3,20 @@ package com.nflg.mobilebroken.admin.event;
|
||||||
import cn.hutool.core.collection.CollectionUtil;
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
import com.nflg.mobilebroken.admin.service.ShengWangService;
|
import com.nflg.mobilebroken.admin.service.ShengWangService;
|
||||||
import com.nflg.mobilebroken.admin.service.SsePushService;
|
import com.nflg.mobilebroken.admin.service.SsePushService;
|
||||||
|
import com.nflg.mobilebroken.common.constant.Constant;
|
||||||
import com.nflg.mobilebroken.common.constant.TicketState;
|
import com.nflg.mobilebroken.common.constant.TicketState;
|
||||||
import com.nflg.mobilebroken.common.pojo.dto.ChatMessageDTO;
|
import com.nflg.mobilebroken.common.pojo.dto.*;
|
||||||
import com.nflg.mobilebroken.repository.service.TicketChatService;
|
import com.nflg.mobilebroken.repository.service.TicketChatService;
|
||||||
|
import com.nflg.mobilebroken.starter.service.UniPushService;
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.ApplicationContextAware;
|
import org.springframework.context.ApplicationContextAware;
|
||||||
import org.springframework.context.ApplicationEvent;
|
import org.springframework.context.ApplicationEvent;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class TicketCallEndEvent extends ApplicationEvent implements ApplicationContextAware {
|
public class TicketCallEndEvent extends ApplicationEvent implements ApplicationContextAware {
|
||||||
|
|
||||||
|
|
@ -22,6 +25,8 @@ public class TicketCallEndEvent extends ApplicationEvent implements ApplicationC
|
||||||
private SsePushService ssePushService;
|
private SsePushService ssePushService;
|
||||||
private TicketChatService ticketChatService;
|
private TicketChatService ticketChatService;
|
||||||
private ShengWangService shengWangService;
|
private ShengWangService shengWangService;
|
||||||
|
private StringRedisTemplate stringRedisTemplate;
|
||||||
|
private UniPushService uniPushService;
|
||||||
|
|
||||||
public TicketCallEndEvent(Object source, Integer ticketId) {
|
public TicketCallEndEvent(Object source, Integer ticketId) {
|
||||||
super(source);
|
super(source);
|
||||||
|
|
@ -32,23 +37,47 @@ public class TicketCallEndEvent extends ApplicationEvent implements ApplicationC
|
||||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||||
this.ssePushService = applicationContext.getBean(SsePushService.class);
|
this.ssePushService = applicationContext.getBean(SsePushService.class);
|
||||||
this.ticketChatService = applicationContext.getBean(TicketChatService.class);
|
this.ticketChatService = applicationContext.getBean(TicketChatService.class);
|
||||||
|
this.shengWangService = applicationContext.getBean(ShengWangService.class);
|
||||||
|
this.stringRedisTemplate = applicationContext.getBean(StringRedisTemplate.class);
|
||||||
|
this.uniPushService = applicationContext.getBean(UniPushService.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void send() throws IOException, InterruptedException {
|
public void send() throws IOException, InterruptedException {
|
||||||
TimeUnit.SECONDS.sleep(2);
|
if (Objects.equals(0L, stringRedisTemplate.opsForSet().size(Constant.REDIS_KEY_TICKET_CALL_WAIT + ticketId))) {
|
||||||
if (CollectionUtil.isEmpty(shengWangService.getChannelUsers("ticket-" + ticketId))) {
|
ShengWangChannelUserListDTO channelUserListDTO = shengWangService.getChannelUsers("ticket" + ticketId);
|
||||||
ChatMessageDTO message = new ChatMessageDTO()
|
if (!channelUserListDTO.isChannelEexist() || channelUserListDTO.getUsers().size() <= 1) {
|
||||||
.setId(cn.hutool.core.util.IdUtil.getSnowflakeNextIdStr())
|
ChatMessageDTO message = new ChatMessageDTO()
|
||||||
.setFrom("call")
|
.setId(cn.hutool.core.util.IdUtil.getSnowflakeNextIdStr())
|
||||||
.setTicketState(TicketState.Processing.getState())
|
.setFrom("call")
|
||||||
.setSenderId(0)
|
.setTicketState(TicketState.Processing.getState())
|
||||||
.setSenderName("通话助手")
|
.setSenderId(0)
|
||||||
.setContent("视频通话已结束")
|
.setSenderName("通话助手")
|
||||||
.setCreateTime(Instant.now());
|
.setContent("视频通话已结束")
|
||||||
ticketChatService.addMessage(ticketId, message);
|
.setCreateTime(Instant.now());
|
||||||
//推送消息
|
ticketChatService.addMessage(ticketId, message);
|
||||||
ssePushService.sendTicketMessageToAdmin(ticketId, message);
|
//推送消息
|
||||||
ssePushService.sendTicketMessageToApp(ticketId, message);
|
ssePushService.sendTicketMessageToAdmin(ticketId, message);
|
||||||
|
ssePushService.sendTicketMessageToApp(ticketId, message);
|
||||||
|
ssePushService.sendTicketCallEnd(ticketId);
|
||||||
|
Integer userId = CollectionUtil.get(channelUserListDTO.getUsers(), 0);
|
||||||
|
if (Objects.nonNull(userId)) {
|
||||||
|
String from = userId.toString().startsWith("1") ? "app" : "admin";
|
||||||
|
userId = Integer.valueOf(userId.toString().substring(1));
|
||||||
|
uniPushService.send(new UniPushMessage()
|
||||||
|
.setSenderId(from + "-uid-0")//不重要
|
||||||
|
.setReceiverId(from + "-uid-" + userId)
|
||||||
|
.setSendData(new UniPushMessageBody()
|
||||||
|
.setTitle("视频通话结束")
|
||||||
|
.setPayload(new UniPushMessageCallPayload()
|
||||||
|
.setTicketId(ticketId)
|
||||||
|
.setUserId(userId)
|
||||||
|
.setCategory("ticketCallEnd")
|
||||||
|
.setFrom("admin")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -45,6 +45,10 @@ public class ShengWangService {
|
||||||
@Value("${shengwang.rtc.customerSecret}")
|
@Value("${shengwang.rtc.customerSecret}")
|
||||||
private String customerSecret;
|
private String customerSecret;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有频道
|
||||||
|
* @return 频道列表
|
||||||
|
*/
|
||||||
public ShengWangChannelDTO getAllChannels() throws IOException, InterruptedException {
|
public ShengWangChannelDTO getAllChannels() throws IOException, InterruptedException {
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
.GET()
|
.GET()
|
||||||
|
|
@ -59,6 +63,26 @@ public class ShengWangService {
|
||||||
return result.getData();
|
return result.getData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询频道用户列表
|
||||||
|
* @param channelName 频道名称
|
||||||
|
* @return 用户列表
|
||||||
|
*/
|
||||||
|
public ShengWangChannelUserListDTO getChannelUsers(String channelName) throws IOException, InterruptedException {
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.GET()
|
||||||
|
.header("Authorization", generateAuthorization(customerKey, customerSecret))
|
||||||
|
.uri(URI.create(baseUrl + "/v1/channel/user/" + appId + "/" + channelName))
|
||||||
|
.build();
|
||||||
|
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
|
log.debug("getChannelUsers Response:" + response.body());
|
||||||
|
VUtils.trueThrowBusinessError(response.statusCode() != 200).throwMessage("请求失败");
|
||||||
|
ShengWangResponse<ShengWangChannelUserListDTO> result = objectMapper.readValue(response.body(), new TypeReference<>() {
|
||||||
|
});
|
||||||
|
VUtils.trueThrowBusinessError(!result.isSuccess()).throwMessage("查询用户列表失败");
|
||||||
|
return result.getData();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建规则
|
* 创建规则
|
||||||
* @param channelName 频道名称
|
* @param channelName 频道名称
|
||||||
|
|
@ -141,18 +165,4 @@ public class ShengWangService {
|
||||||
// 创建 authorization header
|
// 创建 authorization header
|
||||||
return "Basic " + base64Credentials;
|
return "Basic " + base64Credentials;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Integer> getChannelUsers(String channelName) throws IOException, InterruptedException {
|
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
|
||||||
.GET()
|
|
||||||
.header("Authorization", generateAuthorization(customerKey, customerSecret))
|
|
||||||
.uri(URI.create(baseUrl + "/v1/channel/user/" + appId + "/" + channelName))
|
|
||||||
.build();
|
|
||||||
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
|
||||||
log.debug("getChannelUsers Response:" + response.body());
|
|
||||||
VUtils.trueThrowBusinessError(response.statusCode() != 200).throwMessage("请求失败");
|
|
||||||
ShengWangChannelUserResponseDTO result = objectMapper.readValue(response.body(), ShengWangChannelUserResponseDTO.class);
|
|
||||||
VUtils.trueThrowBusinessError(!result.getSuccess()).throwMessage("获取频道用户失败");
|
|
||||||
return result.getData().isChannel_exist()?result.getData().getUsers():null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -304,4 +304,28 @@ public class SsePushService {
|
||||||
log.error("发送消息出错", e);
|
log.error("发送消息出错", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void sendTicketCallEnd(Integer ticketId) {
|
||||||
|
try {
|
||||||
|
TicketMessagePushRequest request = new TicketMessagePushRequest()
|
||||||
|
.setTicketId(ticketId)
|
||||||
|
.setMessage(new PushMessageDTO()
|
||||||
|
.setType("ticketCallEnd")
|
||||||
|
.setData(new PushMessageDataBody()
|
||||||
|
.setTargetId(ticketId)
|
||||||
|
.setType("ticketCallEnd")
|
||||||
|
.setData(new UniPushMessageCallPayload()
|
||||||
|
.setTicketId(ticketId)
|
||||||
|
.setFrom("admin")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
ApiResult<?> result = sendMessage(request, "app");
|
||||||
|
log.debug("发送消息结果:{}", JSONUtil.toJsonStr(result));
|
||||||
|
result = sendMessage(request, "admin");
|
||||||
|
log.debug("发送消息结果:{}", JSONUtil.toJsonStr(result));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("发送消息出错", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,16 @@
|
||||||
package com.nflg.mobilebroken.admin.task;
|
package com.nflg.mobilebroken.admin.task;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollectionUtil;
|
|
||||||
import com.nflg.mobilebroken.admin.service.ShengWangService;
|
import com.nflg.mobilebroken.admin.service.ShengWangService;
|
||||||
import com.nflg.mobilebroken.common.constant.Constant;
|
|
||||||
import com.nflg.mobilebroken.common.pojo.dto.ShengWangChannelDTO;
|
|
||||||
import com.nflg.mobilebroken.common.pojo.dto.ShengWangChannelInfoDTO;
|
|
||||||
import com.nflg.mobilebroken.common.util.IdUtil;
|
|
||||||
import com.nflg.mobilebroken.repository.entity.TicketCall;
|
|
||||||
import com.nflg.mobilebroken.repository.entity.TicketCallJoin;
|
|
||||||
import com.nflg.mobilebroken.repository.service.ITicketCallJoinService;
|
import com.nflg.mobilebroken.repository.service.ITicketCallJoinService;
|
||||||
import com.nflg.mobilebroken.repository.service.ITicketCallService;
|
import com.nflg.mobilebroken.repository.service.ITicketCallService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.slf4j.MDC;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@ConditionalOnProperty(name = "shengwang.sync.enable", havingValue = "true", matchIfMissing = true)
|
@ConditionalOnProperty(name = "shengwang.sync.enable", havingValue = "true", matchIfMissing = true)
|
||||||
@Component
|
@Component
|
||||||
|
|
@ -45,83 +33,83 @@ public class ShengWangScheduledTasks {
|
||||||
@Transactional
|
@Transactional
|
||||||
@Scheduled(cron = "0 0/1 * * * ?")
|
@Scheduled(cron = "0 0/1 * * * ?")
|
||||||
public void syncState() throws Exception {
|
public void syncState() throws Exception {
|
||||||
MDC.put("traceId", IdUtil.getIdStr());
|
// MDC.put("traceId", IdUtil.getIdStr());
|
||||||
log.info("开始执行声网通话状态同步");
|
// log.info("开始执行声网通话状态同步");
|
||||||
ShengWangChannelDTO dto = shengWangService.getAllChannels();
|
// ShengWangChannelDTO dto = shengWangService.getAllChannels();
|
||||||
log.info("共{}个频道", dto.getTotalSize());
|
// log.info("共{}个频道", dto.getTotalSize());
|
||||||
log.info("将不存在列表中的通话设置为已结束状态");
|
// log.info("将不存在列表中的通话设置为已结束状态");
|
||||||
List<TicketCall> ticketCalls = ticketCallService.lambdaQuery()
|
// List<TicketCall> ticketCalls = ticketCallService.lambdaQuery()
|
||||||
.ne(TicketCall::getState, 2)
|
// .ne(TicketCall::getState, 2)
|
||||||
.notIn(dto.getTotalSize() > 0, TicketCall::getTicketId, dto.getChannels()
|
// .notIn(dto.getTotalSize() > 0, TicketCall::getTicketId, dto.getChannels()
|
||||||
.stream()
|
// .stream()
|
||||||
.map(o -> Integer.valueOf(o.getChannelName().replace("ticket", "")))
|
// .map(o -> Integer.valueOf(o.getChannelName().replace("ticket", "")))
|
||||||
.collect(Collectors.toList()))
|
// .collect(Collectors.toList()))
|
||||||
.list();
|
// .list();
|
||||||
if (CollectionUtil.isNotEmpty(ticketCalls)) {
|
// if (CollectionUtil.isNotEmpty(ticketCalls)) {
|
||||||
ticketCalls.forEach(ticketCall -> {
|
// ticketCalls.forEach(ticketCall -> {
|
||||||
ticketCall.setState(2);
|
// ticketCall.setState(2);
|
||||||
ticketCall.setHangupTime(LocalDateTime.now());
|
// ticketCall.setHangupTime(LocalDateTime.now());
|
||||||
ticketCallService.updateById(ticketCall);
|
// ticketCallService.updateById(ticketCall);
|
||||||
ticketCallJoinService.lambdaUpdate()
|
// ticketCallJoinService.lambdaUpdate()
|
||||||
.set(TicketCallJoin::getState, 2)
|
// .set(TicketCallJoin::getState, 2)
|
||||||
// .set(TicketCallJoin::getHangupTime, LocalDateTime.now())
|
//// .set(TicketCallJoin::getHangupTime, LocalDateTime.now())
|
||||||
.eq(TicketCallJoin::getCallId, ticketCall.getId())
|
// .eq(TicketCallJoin::getCallId, ticketCall.getId())
|
||||||
.update();
|
// .update();
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
for (ShengWangChannelInfoDTO info : dto.getChannels()) {
|
// for (ShengWangChannelInfoDTO info : dto.getChannels()) {
|
||||||
log.info("处理频道:{}", info.getChannelName());
|
// log.info("处理频道:{}", info.getChannelName());
|
||||||
TicketCall ticketCall = ticketCallService.lambdaQuery()
|
// TicketCall ticketCall = ticketCallService.lambdaQuery()
|
||||||
.eq(TicketCall::getTicketId, Integer.valueOf(info.getChannelName().replace("ticket", "")))
|
// .eq(TicketCall::getTicketId, Integer.valueOf(info.getChannelName().replace("ticket", "")))
|
||||||
.eq(TicketCall::getState, 1)
|
// .eq(TicketCall::getState, 1)
|
||||||
.one();
|
// .one();
|
||||||
if (Objects.nonNull(ticketCall)) {
|
// if (Objects.nonNull(ticketCall)) {
|
||||||
log.info("获取频道用户");
|
// log.info("获取频道用户");
|
||||||
List<Integer> channelUsers = shengWangService.getChannelUsers(info.getChannelName());
|
// List<Integer> channelUsers = shengWangService.getChannelUsers(info.getChannelName());
|
||||||
log.info("频道用户:{}", channelUsers);
|
// log.info("频道用户:{}", channelUsers);
|
||||||
if (CollectionUtil.isEmpty(channelUsers)) {
|
// if (CollectionUtil.isEmpty(channelUsers)) {
|
||||||
ticketCallJoinService.lambdaUpdate()
|
// ticketCallJoinService.lambdaUpdate()
|
||||||
.set(TicketCallJoin::getState, 2)
|
// .set(TicketCallJoin::getState, 2)
|
||||||
// .set(TicketCallJoin::getHangupTime, LocalDateTime.now())
|
//// .set(TicketCallJoin::getHangupTime, LocalDateTime.now())
|
||||||
.eq(TicketCallJoin::getCallId, ticketCall.getId())
|
// .eq(TicketCallJoin::getCallId, ticketCall.getId())
|
||||||
.update();
|
// .update();
|
||||||
} else {
|
// } else {
|
||||||
//用户端
|
// //用户端
|
||||||
List<Integer> userIds = channelUsers.stream()
|
// List<Integer> userIds = channelUsers.stream()
|
||||||
.map(String::valueOf)
|
// .map(String::valueOf)
|
||||||
.filter(userId -> String.valueOf(userId).startsWith("1"))
|
// .filter(userId -> String.valueOf(userId).startsWith("1"))
|
||||||
.map(this::getUserId)
|
// .map(this::getUserId)
|
||||||
.collect(Collectors.toList());
|
// .collect(Collectors.toList());
|
||||||
log.info("客户端用户:{}", userIds);
|
// log.info("客户端用户:{}", userIds);
|
||||||
if (CollectionUtil.isNotEmpty(userIds)) {
|
// if (CollectionUtil.isNotEmpty(userIds)) {
|
||||||
ticketCallJoinService.lambdaUpdate()
|
// ticketCallJoinService.lambdaUpdate()
|
||||||
.set(TicketCallJoin::getState, 2)
|
// .set(TicketCallJoin::getState, 2)
|
||||||
// .set(TicketCallJoin::getHangupTime, LocalDateTime.now())
|
//// .set(TicketCallJoin::getHangupTime, LocalDateTime.now())
|
||||||
.eq(TicketCallJoin::getCallId, ticketCall.getId())
|
// .eq(TicketCallJoin::getCallId, ticketCall.getId())
|
||||||
.eq(TicketCallJoin::getFrom, Constant.FROM_APP)
|
// .eq(TicketCallJoin::getFrom, Constant.FROM_APP)
|
||||||
.notIn(TicketCallJoin::getUserId, userIds)
|
// .notIn(TicketCallJoin::getUserId, userIds)
|
||||||
.update();
|
// .update();
|
||||||
}
|
// }
|
||||||
//管理端
|
// //管理端
|
||||||
userIds = channelUsers.stream()
|
// userIds = channelUsers.stream()
|
||||||
.map(String::valueOf)
|
// .map(String::valueOf)
|
||||||
.filter(userId -> String.valueOf(userId).startsWith("2"))
|
// .filter(userId -> String.valueOf(userId).startsWith("2"))
|
||||||
.map(this::getUserId)
|
// .map(this::getUserId)
|
||||||
.collect(Collectors.toList());
|
// .collect(Collectors.toList());
|
||||||
log.info("管理端用户:{}", userIds);
|
// log.info("管理端用户:{}", userIds);
|
||||||
if (CollectionUtil.isNotEmpty(userIds)) {
|
// if (CollectionUtil.isNotEmpty(userIds)) {
|
||||||
ticketCallJoinService.lambdaUpdate()
|
// ticketCallJoinService.lambdaUpdate()
|
||||||
.set(TicketCallJoin::getState, 2)
|
// .set(TicketCallJoin::getState, 2)
|
||||||
// .set(TicketCallJoin::getHangupTime, LocalDateTime.now())
|
//// .set(TicketCallJoin::getHangupTime, LocalDateTime.now())
|
||||||
.eq(TicketCallJoin::getCallId, ticketCall.getId())
|
// .eq(TicketCallJoin::getCallId, ticketCall.getId())
|
||||||
.eq(TicketCallJoin::getFrom, Constant.FROM_ADMIN)
|
// .eq(TicketCallJoin::getFrom, Constant.FROM_ADMIN)
|
||||||
.notIn(TicketCallJoin::getUserId, userIds)
|
// .notIn(TicketCallJoin::getUserId, userIds)
|
||||||
.update();
|
// .update();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
log.info("执行声网通话状态同步完毕");
|
// log.info("执行声网通话状态同步完毕");
|
||||||
}
|
}
|
||||||
|
|
||||||
private Integer getUserId(String userId){
|
private Integer getUserId(String userId){
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import cn.hutool.core.util.IdUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.nflg.mobilebroken.cfs.publisher.TicketEventPublisher;
|
import com.nflg.mobilebroken.cfs.publisher.TicketEventPublisher;
|
||||||
|
import com.nflg.mobilebroken.cfs.service.ShengWangService;
|
||||||
import com.nflg.mobilebroken.cfs.service.SsePushService;
|
import com.nflg.mobilebroken.cfs.service.SsePushService;
|
||||||
import com.nflg.mobilebroken.common.constant.Constant;
|
import com.nflg.mobilebroken.common.constant.Constant;
|
||||||
import com.nflg.mobilebroken.common.constant.TicketState;
|
import com.nflg.mobilebroken.common.constant.TicketState;
|
||||||
|
|
@ -13,10 +14,7 @@ import com.nflg.mobilebroken.common.pojo.PageData;
|
||||||
import com.nflg.mobilebroken.common.pojo.dto.*;
|
import com.nflg.mobilebroken.common.pojo.dto.*;
|
||||||
import com.nflg.mobilebroken.common.pojo.request.*;
|
import com.nflg.mobilebroken.common.pojo.request.*;
|
||||||
import com.nflg.mobilebroken.common.pojo.vo.*;
|
import com.nflg.mobilebroken.common.pojo.vo.*;
|
||||||
import com.nflg.mobilebroken.common.util.AppUserUtil;
|
import com.nflg.mobilebroken.common.util.*;
|
||||||
import com.nflg.mobilebroken.common.util.MultilingualUtil;
|
|
||||||
import com.nflg.mobilebroken.common.util.PageUtil;
|
|
||||||
import com.nflg.mobilebroken.common.util.VUtils;
|
|
||||||
import com.nflg.mobilebroken.repository.entity.*;
|
import com.nflg.mobilebroken.repository.entity.*;
|
||||||
import com.nflg.mobilebroken.repository.service.*;
|
import com.nflg.mobilebroken.repository.service.*;
|
||||||
import com.nflg.mobilebroken.starter.service.UniPushService;
|
import com.nflg.mobilebroken.starter.service.UniPushService;
|
||||||
|
|
@ -28,8 +26,10 @@ import javax.annotation.Resource;
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
import javax.validation.constraints.NotBlank;
|
import javax.validation.constraints.NotBlank;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.io.IOException;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -99,6 +99,9 @@ public class TicketController extends ControllerBase {
|
||||||
// @Resource
|
// @Resource
|
||||||
// private ITicketCallJoinService ticketCallJoinService;
|
// private ITicketCallJoinService ticketCallJoinService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ShengWangService shengWangService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 搜索设备
|
* 搜索设备
|
||||||
* @param request 搜索条件
|
* @param request 搜索条件
|
||||||
|
|
@ -525,6 +528,8 @@ public class TicketController extends ControllerBase {
|
||||||
ssePushService.sendTicketCallToAdmin(appUser, handlerUserId, ticketId);
|
ssePushService.sendTicketCallToAdmin(appUser, handlerUserId, ticketId);
|
||||||
// ticketCallService.add(ticketId, AppUserUtil.getUserId(),Constant.FROM_APP, handlerUserId, Constant.FROM_ADMIN);
|
// ticketCallService.add(ticketId, AppUserUtil.getUserId(),Constant.FROM_APP, handlerUserId, Constant.FROM_ADMIN);
|
||||||
ticketEventPublisher.publishTicketCallBeginEvent(ticketId,appUser.getName());
|
ticketEventPublisher.publishTicketCallBeginEvent(ticketId,appUser.getName());
|
||||||
|
stringRedisTemplate.opsForSet().add(Constant.REDIS_KEY_TICKET_CALL_WAIT + ticketId, Constant.FROM_ADMIN + "-" + handlerUserId);
|
||||||
|
stringRedisTemplate.expire(Constant.REDIS_KEY_TICKET_CALL_WAIT + ticketId, 1, TimeUnit.MINUTES);
|
||||||
return ApiResult.success();
|
return ApiResult.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -533,7 +538,7 @@ public class TicketController extends ControllerBase {
|
||||||
* @param ticketId 工单编号
|
* @param ticketId 工单编号
|
||||||
*/
|
*/
|
||||||
@GetMapping("call/joinChannel")
|
@GetMapping("call/joinChannel")
|
||||||
public ApiResult<Void> joinChannel(@Valid @RequestParam @NotNull Integer ticketId){
|
public ApiResult<Void> joinChannel(@Valid @RequestParam @NotNull Integer ticketId) throws IOException, InterruptedException {
|
||||||
Ticket ticket = ticketService.getById(ticketId);
|
Ticket ticket = ticketService.getById(ticketId);
|
||||||
VUtils.trueThrowBusinessError(Objects.isNull(ticket)).throwMessage("工单不存在");
|
VUtils.trueThrowBusinessError(Objects.isNull(ticket)).throwMessage("工单不存在");
|
||||||
VUtils.trueThrowBusinessError(!Objects.equals(ticket.getState(), TicketState.Processing.getState()))
|
VUtils.trueThrowBusinessError(!Objects.equals(ticket.getState(), TicketState.Processing.getState()))
|
||||||
|
|
@ -560,6 +565,24 @@ public class TicketController extends ControllerBase {
|
||||||
// )
|
// )
|
||||||
// )
|
// )
|
||||||
// );
|
// );
|
||||||
|
ShengWangChannelUserListDTO channelUsers = shengWangService.getChannelUsers("ticket" + ticketId);
|
||||||
|
VUtils.trueThrowBusinessError(!channelUsers.isChannelEexist()).throwMessage("通话已结束");
|
||||||
|
VUtils.trueThrowBusinessError(channelUsers.getUsers().contains(ShengWangUtil.getUserId(AppUserUtil.getUserId(), AppUserUtil.getFrom())))
|
||||||
|
.throwMessage("你已在通话中");
|
||||||
|
ssePushService.sendTicketCallJoined(AppUserUtil.getUserId(), ticketId, AppUserUtil.getFrom());
|
||||||
|
uniPushService.send(new UniPushMessage()
|
||||||
|
.setSenderId(AppUserUtil.getFrom() + "-uid-" + AppUserUtil.getUserId())//不重要
|
||||||
|
.setReceiverId(AppUserUtil.getFrom() + "-uid-" + AppUserUtil.getUserId())
|
||||||
|
.setSendData(new UniPushMessageBody()
|
||||||
|
.setTitle("视频通话")
|
||||||
|
.setPayload(new UniPushMessageCallPayload()
|
||||||
|
.setTicketId(ticketId)
|
||||||
|
.setUserId(AppUserUtil.getUserId())
|
||||||
|
.setCategory("ticketCallJoined")
|
||||||
|
.setFrom("app")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
return ApiResult.success();
|
return ApiResult.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -568,56 +591,90 @@ public class TicketController extends ControllerBase {
|
||||||
* @param request 请求信息
|
* @param request 请求信息
|
||||||
*/
|
*/
|
||||||
@PostMapping("call/hangUp")
|
@PostMapping("call/hangUp")
|
||||||
public ApiResult<Void> hangUp(@Valid @RequestBody TicketCallHangUpRequest request) {
|
public ApiResult<Void> hangUp(@Valid @RequestBody TicketCallHangUpRequest request) throws IOException, InterruptedException {
|
||||||
// TicketCall ticketCall = ticketCallService.getLast(request.getTicketId());
|
// TicketCall ticketCall = ticketCallService.getLast(request.getTicketId());
|
||||||
if (request.getReject()) {
|
// if (request.getReject()) {
|
||||||
// if (Objects.isNull(ticketCall)) return ApiResult.success();
|
//// if (Objects.isNull(ticketCall)) return ApiResult.success();
|
||||||
if (StrUtil.equals(request.getFrom(), Constant.FROM_APP) && Objects.equals(AppUserUtil.getUserId(), request.getFromUserId())) {
|
// if (StrUtil.equals(request.getFrom(), Constant.FROM_APP) && Objects.equals(AppUserUtil.getUserId(), request.getFromUserId())) {
|
||||||
AppUser appUser = appUserService.getById(AppUserUtil.getUserId());
|
// AppUser appUser = appUserService.getById(AppUserUtil.getUserId());
|
||||||
Ticket ticket = ticketService.getById(request.getTicketId());
|
// Ticket ticket = ticketService.getById(request.getTicketId());
|
||||||
int handlerId = Integer.parseInt(StrUtil.split(ticket.getHandle(), ",").stream().findFirst().get());
|
// int handlerId = Integer.parseInt(StrUtil.split(ticket.getHandle(), ",").stream().findFirst().get());
|
||||||
uniPushService.send(new UniPushMessage()
|
// uniPushService.send(new UniPushMessage()
|
||||||
.setSenderId(ticket.getUserPlatform() + "-uid-" + appUser.getId())
|
// .setSenderId(ticket.getUserPlatform() + "-uid-" + appUser.getId())
|
||||||
.setReceiverId("admin-uid-" + handlerId)
|
// .setReceiverId("admin-uid-" + handlerId)
|
||||||
.setSendData(new UniPushMessageBody()
|
// .setSendData(new UniPushMessageBody()
|
||||||
.setTitle("挂断视频通话")
|
// .setTitle("挂断视频通话")
|
||||||
.setContent(appUser.getName() + "挂断了与您的视频通话")
|
// .setContent(appUser.getName() + "挂断了与您的视频通话")
|
||||||
.setPayload(new UniPushMessageCallPayload()
|
// .setPayload(new UniPushMessageCallPayload()
|
||||||
.setTicketId(request.getTicketId())
|
// .setTicketId(request.getTicketId())
|
||||||
.setUserId(appUser.getId())
|
// .setUserId(appUser.getId())
|
||||||
.setUserName(appUser.getName())
|
// .setUserName(appUser.getName())
|
||||||
.setUserAvatar(appUser.getAvatar())
|
// .setUserAvatar(appUser.getAvatar())
|
||||||
.setCategory("ticketCallCancel")
|
// .setCategory("ticketCallCancel")
|
||||||
.setFrom("app")
|
// .setFrom("app")
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
);
|
// );
|
||||||
ssePushService.sendTicketCallCancelToAdmin(request.getTicketId(), handlerId, appUser);
|
// ssePushService.sendTicketCallCancelToAdmin(request.getTicketId(), handlerId, appUser);
|
||||||
} else {
|
// } else {
|
||||||
AppUser appUser = appUserService.getById(AppUserUtil.getUserId());
|
// AppUser appUser = appUserService.getById(AppUserUtil.getUserId());
|
||||||
Ticket ticket = ticketService.getById(request.getTicketId());
|
// Ticket ticket = ticketService.getById(request.getTicketId());
|
||||||
uniPushService.send(new UniPushMessage()
|
// uniPushService.send(new UniPushMessage()
|
||||||
.setSenderId(ticket.getUserPlatform() + "-uid-" + appUser.getId())
|
// .setSenderId(ticket.getUserPlatform() + "-uid-" + appUser.getId())
|
||||||
.setReceiverId("admin-uid-" + request.getFromUserId())
|
// .setReceiverId("admin-uid-" + request.getFromUserId())
|
||||||
.setSendData(new UniPushMessageBody()
|
// .setSendData(new UniPushMessageBody()
|
||||||
.setTitle("拒绝视频通话")
|
// .setTitle("拒绝视频通话")
|
||||||
.setContent(appUser.getName() + "拒绝与您视频通话")
|
// .setContent(appUser.getName() + "拒绝与您视频通话")
|
||||||
.setPayload(new UniPushMessageCallPayload()
|
// .setPayload(new UniPushMessageCallPayload()
|
||||||
.setTicketId(request.getTicketId())
|
// .setTicketId(request.getTicketId())
|
||||||
.setUserId(appUser.getId())
|
// .setUserId(appUser.getId())
|
||||||
.setUserName(appUser.getName())
|
// .setUserName(appUser.getName())
|
||||||
.setUserAvatar(appUser.getAvatar())
|
// .setUserAvatar(appUser.getAvatar())
|
||||||
.setCategory("ticketCallHangUp")
|
// .setCategory("ticketCallHangUp")
|
||||||
.setFrom("app")
|
// .setFrom("app")
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
);
|
// );
|
||||||
ssePushService.sendTicketCallHangUpToAdmin(request.getTicketId(), request.getFromUserId(), appUser);
|
// ssePushService.sendTicketCallHangUpToAdmin(request.getTicketId(), request.getFromUserId(), appUser);
|
||||||
}
|
// }
|
||||||
}
|
|
||||||
// if (ticketCallJoinService.hangUp(ticketCall.getId(), AppUserUtil.getUserId(), Constant.FROM_APP, request.getReject())) {
|
|
||||||
ticketEventPublisher.publishTicketCallEndEvent(request.getTicketId());
|
|
||||||
// }
|
// }
|
||||||
|
//// if (ticketCallJoinService.hangUp(ticketCall.getId(), AppUserUtil.getUserId(), Constant.FROM_APP, request.getReject())) {
|
||||||
|
// ticketEventPublisher.publishTicketCallEndEvent(request.getTicketId());
|
||||||
|
//// }
|
||||||
|
if (StrUtil.equals(request.getFrom(), AppUserUtil.getFrom()) && Objects.equals(request.getFromUserId(), AppUserUtil.getUserId())) {
|
||||||
|
Set<String> userIds = stringRedisTemplate.opsForSet().members(Constant.REDIS_KEY_TICKET_CALL_WAIT + request.getTicketId());
|
||||||
|
if (CollectionUtil.isNotEmpty(userIds)) {
|
||||||
|
userIds.forEach(uid -> {
|
||||||
|
uniPushService.send(new UniPushMessage()
|
||||||
|
.setSenderId(uid)//不重要
|
||||||
|
.setReceiverId(uid)
|
||||||
|
.setSendData(new UniPushMessageBody()
|
||||||
|
.setTitle("视频通话结束")
|
||||||
|
.setPayload(new UniPushMessageCallPayload()
|
||||||
|
.setTicketId(request.getTicketId())
|
||||||
|
.setUserId(Integer.valueOf(StrUtil.split(uid, "-").get(1)))
|
||||||
|
.setCategory("ticketCallEnd")
|
||||||
|
.setFrom("app")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
stringRedisTemplate.delete(Constant.REDIS_KEY_TICKET_CALL_WAIT + request.getTicketId());
|
||||||
|
} else {
|
||||||
|
stringRedisTemplate.opsForSet().remove(Constant.REDIS_KEY_TICKET_CALL_WAIT + request.getTicketId(), Constant.FROM_APP + "-" + AppUserUtil.getUserId());
|
||||||
|
}
|
||||||
|
ticketEventPublisher.publishTicketCallEndEvent(request.getTicketId());
|
||||||
return ApiResult.success();
|
return ApiResult.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取声网频道用户列表
|
||||||
|
* @param ticketId 工单ID
|
||||||
|
* @return 用户列表
|
||||||
|
*/
|
||||||
|
@GetMapping("getShengWangChannelUsers")
|
||||||
|
public ApiResult<List<Integer>> getShengWangChannelUsers(Integer ticketId) throws IOException, InterruptedException {
|
||||||
|
return ApiResult.success(shengWangService.getChannelUsers("ticket" + ticketId).getUsers());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,17 +3,20 @@ package com.nflg.mobilebroken.cfs.event;
|
||||||
import cn.hutool.core.collection.CollectionUtil;
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
import com.nflg.mobilebroken.cfs.service.ShengWangService;
|
import com.nflg.mobilebroken.cfs.service.ShengWangService;
|
||||||
import com.nflg.mobilebroken.cfs.service.SsePushService;
|
import com.nflg.mobilebroken.cfs.service.SsePushService;
|
||||||
|
import com.nflg.mobilebroken.common.constant.Constant;
|
||||||
import com.nflg.mobilebroken.common.constant.TicketState;
|
import com.nflg.mobilebroken.common.constant.TicketState;
|
||||||
import com.nflg.mobilebroken.common.pojo.dto.ChatMessageDTO;
|
import com.nflg.mobilebroken.common.pojo.dto.*;
|
||||||
import com.nflg.mobilebroken.repository.service.TicketChatService;
|
import com.nflg.mobilebroken.repository.service.TicketChatService;
|
||||||
|
import com.nflg.mobilebroken.starter.service.UniPushService;
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.ApplicationContextAware;
|
import org.springframework.context.ApplicationContextAware;
|
||||||
import org.springframework.context.ApplicationEvent;
|
import org.springframework.context.ApplicationEvent;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class TicketCallEndEvent extends ApplicationEvent implements ApplicationContextAware {
|
public class TicketCallEndEvent extends ApplicationEvent implements ApplicationContextAware {
|
||||||
|
|
||||||
|
|
@ -22,6 +25,8 @@ public class TicketCallEndEvent extends ApplicationEvent implements ApplicationC
|
||||||
private SsePushService ssePushService;
|
private SsePushService ssePushService;
|
||||||
private TicketChatService ticketChatService;
|
private TicketChatService ticketChatService;
|
||||||
private ShengWangService shengWangService;
|
private ShengWangService shengWangService;
|
||||||
|
private StringRedisTemplate stringRedisTemplate;
|
||||||
|
private UniPushService uniPushService;
|
||||||
|
|
||||||
public TicketCallEndEvent(Object source,Integer ticketId) {
|
public TicketCallEndEvent(Object source,Integer ticketId) {
|
||||||
super(source);
|
super(source);
|
||||||
|
|
@ -33,23 +38,46 @@ public class TicketCallEndEvent extends ApplicationEvent implements ApplicationC
|
||||||
this.ssePushService = applicationContext.getBean(SsePushService.class);
|
this.ssePushService = applicationContext.getBean(SsePushService.class);
|
||||||
this.ticketChatService = applicationContext.getBean(TicketChatService.class);
|
this.ticketChatService = applicationContext.getBean(TicketChatService.class);
|
||||||
this.shengWangService = applicationContext.getBean(ShengWangService.class);
|
this.shengWangService = applicationContext.getBean(ShengWangService.class);
|
||||||
|
this.stringRedisTemplate = applicationContext.getBean(StringRedisTemplate.class);
|
||||||
|
this.uniPushService = applicationContext.getBean(UniPushService.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void send() throws IOException, InterruptedException {
|
public void send() throws IOException, InterruptedException {
|
||||||
TimeUnit.SECONDS.sleep(2);
|
if (Objects.equals(0L, stringRedisTemplate.opsForSet().size(Constant.REDIS_KEY_TICKET_CALL_WAIT + ticketId))) {
|
||||||
if (CollectionUtil.isEmpty(shengWangService.getChannelUsers("ticket-" + ticketId))) {
|
ShengWangChannelUserListDTO channelUserListDTO = shengWangService.getChannelUsers("ticket" + ticketId);
|
||||||
ChatMessageDTO message = new ChatMessageDTO()
|
if (!channelUserListDTO.isChannelEexist() || channelUserListDTO.getUsers().size() <= 1) {
|
||||||
.setId(cn.hutool.core.util.IdUtil.getSnowflakeNextIdStr())
|
ChatMessageDTO message = new ChatMessageDTO()
|
||||||
.setFrom("call")
|
.setId(cn.hutool.core.util.IdUtil.getSnowflakeNextIdStr())
|
||||||
.setTicketState(TicketState.Processing.getState())
|
.setFrom("call")
|
||||||
.setSenderId(0)
|
.setTicketState(TicketState.Processing.getState())
|
||||||
.setSenderName("通话助手")
|
.setSenderId(0)
|
||||||
.setContent("视频通话已结束")
|
.setSenderName("通话助手")
|
||||||
.setCreateTime(Instant.now());
|
.setContent("视频通话已结束")
|
||||||
ticketChatService.addMessage(ticketId, message);
|
.setCreateTime(Instant.now());
|
||||||
//推送消息
|
ticketChatService.addMessage(ticketId, message);
|
||||||
ssePushService.sendTicketMessageToAdmin(ticketId, message);
|
//推送消息
|
||||||
ssePushService.sendTicketMessageToApp(ticketId, message);
|
ssePushService.sendTicketMessageToAdmin(ticketId, message);
|
||||||
|
ssePushService.sendTicketMessageToApp(ticketId, message);
|
||||||
|
ssePushService.sendTicketCallEnd(ticketId);
|
||||||
|
Integer userId = CollectionUtil.get(channelUserListDTO.getUsers(), 0);
|
||||||
|
if (Objects.nonNull(userId)) {
|
||||||
|
String from = userId.toString().startsWith("1") ? "app" : "admin";
|
||||||
|
userId = Integer.valueOf(userId.toString().substring(1));
|
||||||
|
uniPushService.send(new UniPushMessage()
|
||||||
|
.setSenderId(from + "-uid-0")//不重要
|
||||||
|
.setReceiverId(from + "-uid-" + userId)
|
||||||
|
.setSendData(new UniPushMessageBody()
|
||||||
|
.setTitle("视频通话结束")
|
||||||
|
.setPayload(new UniPushMessageCallPayload()
|
||||||
|
.setTicketId(ticketId)
|
||||||
|
.setUserId(userId)
|
||||||
|
.setCategory("ticketCallEnd")
|
||||||
|
.setFrom("app")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -60,6 +60,26 @@ public class ShengWangService {
|
||||||
return result.getData();
|
return result.getData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询频道用户列表
|
||||||
|
* @param channelName 频道名称
|
||||||
|
* @return 用户列表
|
||||||
|
*/
|
||||||
|
public ShengWangChannelUserListDTO getChannelUsers(String channelName) throws IOException, InterruptedException {
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.GET()
|
||||||
|
.header("Authorization", generateAuthorization(customerKey, customerSecret))
|
||||||
|
.uri(URI.create(baseUrl + "/v1/channel/user/" + appId + "/" + channelName))
|
||||||
|
.build();
|
||||||
|
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
|
log.debug("getChannelUsers Response:" + response.body());
|
||||||
|
VUtils.trueThrowBusinessError(response.statusCode() != 200).throwMessage("请求失败");
|
||||||
|
ShengWangResponse<ShengWangChannelUserListDTO> result = objectMapper.readValue(response.body(), new TypeReference<>() {
|
||||||
|
});
|
||||||
|
VUtils.trueThrowBusinessError(!result.isSuccess()).throwMessage("查询用户列表失败");
|
||||||
|
return result.getData();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建规则
|
* 创建规则
|
||||||
* @param channelName 频道名称
|
* @param channelName 频道名称
|
||||||
|
|
@ -142,18 +162,4 @@ public class ShengWangService {
|
||||||
// 创建 authorization header
|
// 创建 authorization header
|
||||||
return "Basic " + base64Credentials;
|
return "Basic " + base64Credentials;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Integer> getChannelUsers(String channelName) throws IOException, InterruptedException {
|
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
|
||||||
.GET()
|
|
||||||
.header("Authorization", generateAuthorization(customerKey, customerSecret))
|
|
||||||
.uri(URI.create(baseUrl + "/v1/channel/user/" + appId + "/" + channelName))
|
|
||||||
.build();
|
|
||||||
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
|
||||||
log.debug("getChannelUsers Response:" + response.body());
|
|
||||||
VUtils.trueThrowBusinessError(response.statusCode() != 200).throwMessage("请求失败");
|
|
||||||
ShengWangChannelUserResponseDTO result = objectMapper.readValue(response.body(), ShengWangChannelUserResponseDTO.class);
|
|
||||||
VUtils.trueThrowBusinessError(!result.getSuccess()).throwMessage("获取频道用户失败");
|
|
||||||
return result.getData().isChannel_exist() ? result.getData().getUsers() : null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
import javax.validation.constraints.NotBlank;
|
import javax.validation.constraints.NotBlank;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
|
|
@ -244,4 +245,50 @@ public class SsePushService {
|
||||||
log.error("发送消息出错", e);
|
log.error("发送消息出错", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void sendTicketCallJoined(Integer userId, @Valid @NotNull Integer ticketId, String to) {
|
||||||
|
try {
|
||||||
|
PushUserMessageRequest request = new PushUserMessageRequest()
|
||||||
|
.setUserId(userId)
|
||||||
|
.setMessage(new PushMessageDTO()
|
||||||
|
.setType("ticketCallJoined")
|
||||||
|
.setData(new PushMessageDataBody()
|
||||||
|
.setTargetId(ticketId)
|
||||||
|
.setType("ticketCallJoined")
|
||||||
|
.setData(new UniPushMessageCallPayload()
|
||||||
|
.setTicketId(ticketId)
|
||||||
|
.setFrom("app")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
ApiResult<?> result = sendMessageByUser(request, to);
|
||||||
|
log.debug("发送消息结果:{}", JSONUtil.toJsonStr(result));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("发送消息出错", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendTicketCallEnd(Integer ticketId) {
|
||||||
|
try {
|
||||||
|
TicketMessagePushRequest request = new TicketMessagePushRequest()
|
||||||
|
.setTicketId(ticketId)
|
||||||
|
.setMessage(new PushMessageDTO()
|
||||||
|
.setType("ticketCallEnd")
|
||||||
|
.setData(new PushMessageDataBody()
|
||||||
|
.setTargetId(ticketId)
|
||||||
|
.setType("ticketCallEnd")
|
||||||
|
.setData(new UniPushMessageCallPayload()
|
||||||
|
.setTicketId(ticketId)
|
||||||
|
.setFrom("app")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
ApiResult<?> result = sendMessage(request, "app");
|
||||||
|
log.debug("发送消息结果:{}", JSONUtil.toJsonStr(result));
|
||||||
|
result = sendMessage(request, "admin");
|
||||||
|
log.debug("发送消息结果:{}", JSONUtil.toJsonStr(result));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("发送消息出错", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -135,4 +135,6 @@ public class Constant {
|
||||||
public static final String DICTIONARY_PRODUCT_MODULE = "ProductModule";
|
public static final String DICTIONARY_PRODUCT_MODULE = "ProductModule";
|
||||||
|
|
||||||
public static final String TRACE_ID = "traceId";
|
public static final String TRACE_ID = "traceId";
|
||||||
|
|
||||||
|
public static final String REDIS_KEY_TICKET_CALL_WAIT = "ticket:called:wait:";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.nflg.mobilebroken.common.pojo.dto;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ShengWangChannelUserListDTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定频道是否存在
|
||||||
|
*/
|
||||||
|
@JsonProperty("channel_exist")
|
||||||
|
private boolean channelEexist;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 频道内的总人数
|
||||||
|
*/
|
||||||
|
private Integer total;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 频道内所有用户的用户ID
|
||||||
|
*/
|
||||||
|
private List<Integer> users;
|
||||||
|
}
|
||||||
|
|
@ -127,4 +127,9 @@ public class TicketInfoVO {
|
||||||
* 当前用户是否为CQM
|
* 当前用户是否为CQM
|
||||||
*/
|
*/
|
||||||
private Boolean userIsCQM;
|
private Boolean userIsCQM;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前用户是否可发送消息
|
||||||
|
*/
|
||||||
|
private Boolean canSendMessage;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.nflg.mobilebroken.common.util;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.nflg.mobilebroken.common.constant.Constant;
|
||||||
|
|
||||||
|
public class ShengWangUtil {
|
||||||
|
|
||||||
|
public static Integer getUserId(Integer userId, String from) {
|
||||||
|
switch (from) {
|
||||||
|
case Constant.FROM_APP:
|
||||||
|
return Integer.valueOf("1" + StrUtil.padPre(String.valueOf(userId), 9, '0'));
|
||||||
|
case Constant.FROM_ADMIN:
|
||||||
|
return Integer.valueOf("2" + StrUtil.padPre(String.valueOf(userId), 9, '0'));
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
package com.nflg.mobilebroken.repository.entity;
|
package com.nflg.mobilebroken.repository.entity;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
|
@ -47,11 +45,13 @@ public class TicketSolutionAudit implements Serializable {
|
||||||
/**
|
/**
|
||||||
* 审核状态,0:不通过;1:通过
|
* 审核状态,0:不通过;1:通过
|
||||||
*/
|
*/
|
||||||
|
@TableField(updateStrategy = FieldStrategy.ALWAYS)
|
||||||
private Integer state;
|
private Integer state;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 审核不通过的原因
|
* 审核不通过的原因
|
||||||
*/
|
*/
|
||||||
|
@TableField(updateStrategy = FieldStrategy.ALWAYS)
|
||||||
private String reason;
|
private String reason;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import com.nflg.mobilebroken.common.pojo.vo.SolutionReviewDepartmentVO;
|
||||||
import com.nflg.mobilebroken.repository.entity.Ticket;
|
import com.nflg.mobilebroken.repository.entity.Ticket;
|
||||||
import com.nflg.mobilebroken.repository.entity.TicketSolutionAudit;
|
import com.nflg.mobilebroken.repository.entity.TicketSolutionAudit;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -28,4 +29,6 @@ public interface ITicketSolutionAuditService extends IService<TicketSolutionAudi
|
||||||
boolean pass(Integer ticketId);
|
boolean pass(Integer ticketId);
|
||||||
|
|
||||||
TicketSolutionAudit getByTicketAndUser(Integer ticketId, Integer userId);
|
TicketSolutionAudit getByTicketAndUser(Integer ticketId, Integer userId);
|
||||||
|
|
||||||
|
boolean canUpdate(@NotNull Integer ticketId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -77,12 +77,12 @@ public class TicketSolutionAuditServiceImpl extends ServiceImpl<TicketSolutionAu
|
||||||
List<TicketSolutionAudit> forUpdate=new ArrayList<>();
|
List<TicketSolutionAudit> forUpdate=new ArrayList<>();
|
||||||
Ticket ticket=ticketService.getById(request.getTicketId());
|
Ticket ticket=ticketService.getById(request.getTicketId());
|
||||||
request.getDepartments().forEach(detp->{
|
request.getDepartments().forEach(detp->{
|
||||||
TicketSolutionAudit audit=new TicketSolutionAudit()
|
TicketSolutionAudit audit = new TicketSolutionAudit();
|
||||||
.setTicketId(request.getTicketId())
|
|
||||||
.setDeptName(detp.getDeptName())
|
|
||||||
.setUserId(detp.getUserId())
|
|
||||||
.setCreateTime(LocalDateTime.now());
|
|
||||||
if (Objects.isNull(detp.getId())){
|
if (Objects.isNull(detp.getId())){
|
||||||
|
audit.setTicketId(request.getTicketId());
|
||||||
|
audit.setDeptName(detp.getDeptName());
|
||||||
|
audit.setUserId(detp.getUserId());
|
||||||
|
audit.setCreateTime(LocalDateTime.now());
|
||||||
forAdd.add(audit);
|
forAdd.add(audit);
|
||||||
VUtils.trueThrowBusinessError(lambdaQuery()
|
VUtils.trueThrowBusinessError(lambdaQuery()
|
||||||
.eq(TicketSolutionAudit::getTicketId, request.getTicketId())
|
.eq(TicketSolutionAudit::getTicketId, request.getTicketId())
|
||||||
|
|
@ -104,7 +104,8 @@ public class TicketSolutionAuditServiceImpl extends ServiceImpl<TicketSolutionAu
|
||||||
}else {
|
}else {
|
||||||
audit.setId(detp.getId());
|
audit.setId(detp.getId());
|
||||||
TicketSolutionAudit entity=getById(detp.getId());
|
TicketSolutionAudit entity=getById(detp.getId());
|
||||||
if (!Objects.equals(entity.getUserId(), detp.getUserId())){
|
if (!Objects.equals(entity.getUserId(), detp.getUserId()) || Objects.equals(entity.getState(), 0)) {
|
||||||
|
adminMessageService.remove(0, ticket.getId(), entity.getUserId(), MessageSubType.TicketSolutionAudit.getState());
|
||||||
adminMessageService.add(
|
adminMessageService.add(
|
||||||
new AdminMessage()
|
new AdminMessage()
|
||||||
.setNo(ticket.getNo())
|
.setNo(ticket.getNo())
|
||||||
|
|
@ -117,7 +118,6 @@ public class TicketSolutionAuditServiceImpl extends ServiceImpl<TicketSolutionAu
|
||||||
.setIsRead(false)
|
.setIsRead(false)
|
||||||
.setCreateTime(LocalDateTime.now())
|
.setCreateTime(LocalDateTime.now())
|
||||||
);
|
);
|
||||||
adminMessageService.remove(0,ticket.getId(),entity.getUserId(),MessageSubType.TicketSolutionAudit.getState());
|
|
||||||
audit.setState(null);
|
audit.setState(null);
|
||||||
audit.setReason(null);
|
audit.setReason(null);
|
||||||
}
|
}
|
||||||
|
|
@ -150,7 +150,13 @@ public class TicketSolutionAuditServiceImpl extends ServiceImpl<TicketSolutionAu
|
||||||
.eq(TicketSolutionAudit::getUserId, userId)
|
.eq(TicketSolutionAudit::getUserId, userId)
|
||||||
.eq(TicketSolutionAudit::getState, 1)
|
.eq(TicketSolutionAudit::getState, 1)
|
||||||
.exists())
|
.exists())
|
||||||
.throwMessage("已通过后不能再次审核");
|
.throwMessage("请勿重复审核");
|
||||||
|
VUtils.trueThrowBusinessError(lambdaQuery()
|
||||||
|
.eq(TicketSolutionAudit::getTicketId, request.getTicketId())
|
||||||
|
.eq(TicketSolutionAudit::getUserId, userId)
|
||||||
|
.eq(TicketSolutionAudit::getState, 0)
|
||||||
|
.exists())
|
||||||
|
.throwMessage("请等待CQM修改方案后再审核");
|
||||||
if(lambdaUpdate()
|
if(lambdaUpdate()
|
||||||
.set(TicketSolutionAudit::getState,0)
|
.set(TicketSolutionAudit::getState,0)
|
||||||
.set(TicketSolutionAudit::getReason,request.getReason())
|
.set(TicketSolutionAudit::getReason,request.getReason())
|
||||||
|
|
@ -201,4 +207,10 @@ public class TicketSolutionAuditServiceImpl extends ServiceImpl<TicketSolutionAu
|
||||||
.last("limit 1")
|
.last("limit 1")
|
||||||
.one();
|
.one();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canUpdate(Integer ticketId) {
|
||||||
|
List<TicketSolutionAudit> list = lambdaQuery().eq(TicketSolutionAudit::getTicketId, ticketId).list();
|
||||||
|
return CollectionUtil.isEmpty(list) || list.stream().anyMatch(it -> Objects.equals(0, it.getState()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,10 @@ public class TicketSolutionServiceImpl extends ServiceImpl<TicketSolutionMapper,
|
||||||
VUtils.trueThrowBusinessError(!Objects.equals(ticket.getState(), TicketState.Processing.getState())
|
VUtils.trueThrowBusinessError(!Objects.equals(ticket.getState(), TicketState.Processing.getState())
|
||||||
&& !Objects.equals(ticket.getState(), TicketState.ProcessingCompleted.getState()))
|
&& !Objects.equals(ticket.getState(), TicketState.ProcessingCompleted.getState()))
|
||||||
.throwMessage("当前工单状态不允许修改解决方案");
|
.throwMessage("当前工单状态不允许修改解决方案");
|
||||||
Integer userId=AdminUserUtil.getUserId();
|
VUtils.trueThrowBusinessError(Objects.equals(ticket.getState(), TicketState.ProcessingCompleted.getState())
|
||||||
|
&& !ticketSolutionAuditService.canUpdate(request.getTicketId()))
|
||||||
|
.throwMessage("部门主管审核中,不允许修改解决方案");
|
||||||
|
Integer userId = AdminUserUtil.getUserId();
|
||||||
List<Integer> cqmIds=adminUserService.getCQMIds();
|
List<Integer> cqmIds=adminUserService.getCQMIds();
|
||||||
List<Integer> handleIds= StrUtil.split(ticket.getHandle(),",").stream().map(Integer::parseInt).collect(Collectors.toList());
|
List<Integer> handleIds= StrUtil.split(ticket.getHandle(),",").stream().map(Integer::parseInt).collect(Collectors.toList());
|
||||||
VUtils.trueThrowBusinessError(cqmIds.stream().noneMatch(uid -> Objects.equals(uid, userId))
|
VUtils.trueThrowBusinessError(cqmIds.stream().noneMatch(uid -> Objects.equals(uid, userId))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue