Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
commit
c48a5c34be
|
|
@ -0,0 +1,75 @@
|
||||||
|
package com.nflg.mobilebroken.admin.controller;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.RandomUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.nflg.mobilebroken.common.constant.STATE;
|
||||||
|
import com.nflg.mobilebroken.common.exception.NflgException;
|
||||||
|
import com.nflg.mobilebroken.common.pojo.ApiResult;
|
||||||
|
import com.nflg.mobilebroken.common.util.AdminUserUtil;
|
||||||
|
import com.nflg.mobilebroken.starter.service.FileUploadService;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.validation.Valid;
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件上传相关接口
|
||||||
|
*
|
||||||
|
* @author 曹鹏飞
|
||||||
|
**/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/file")
|
||||||
|
public class FileController extends ControllerBase {
|
||||||
|
|
||||||
|
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");
|
||||||
|
@Resource
|
||||||
|
private FileUploadService fileUploadService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传单个文件
|
||||||
|
*
|
||||||
|
* @param file 要上传的文件
|
||||||
|
* @return 可访问的文件url
|
||||||
|
*/
|
||||||
|
@PostMapping("uploadSingleFile")
|
||||||
|
public ApiResult<String> uploadSingleFile(@RequestParam("file") MultipartFile file) {
|
||||||
|
try {
|
||||||
|
return ApiResult.success(fileUploadService.upload(buildFilePath(file.getOriginalFilename()), file));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new NflgException(STATE.BusinessError, "上传文件失败:" + ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildFilePath(String fileName) {
|
||||||
|
return StrUtil.format("admin/{}/{}/{}/{}", LocalDateTime.now().format(FORMATTER), AdminUserUtil.getUserId(),
|
||||||
|
RandomUtil.randomString(4), fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传多个文件
|
||||||
|
*
|
||||||
|
* @param files 要上传的文件列表
|
||||||
|
* @return 可访问的文件url列表
|
||||||
|
*/
|
||||||
|
@PostMapping("uploadMultipleFiles")
|
||||||
|
public ApiResult<List<String>> uploadMultipleFiles(@Valid @RequestParam("files") @NotEmpty List<MultipartFile> files) {
|
||||||
|
try {
|
||||||
|
List<String> list = new ArrayList<>();
|
||||||
|
for (MultipartFile f : files) {
|
||||||
|
list.add(fileUploadService.upload(buildFilePath(f.getOriginalFilename()), f));
|
||||||
|
}
|
||||||
|
return ApiResult.success(list);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new NflgException(STATE.BusinessError, "上传文件失败:" + ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -24,7 +24,7 @@ public class SSEController extends ControllerBase {
|
||||||
|
|
||||||
@GetMapping(value = "connect", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
|
@GetMapping(value = "connect", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
|
||||||
public SseEmitter connect(@RequestParam String userId) {
|
public SseEmitter connect(@RequestParam String userId) {
|
||||||
SseEmitter sse = adminSSEManagerService.connect(userId);
|
SseEmitter sse = adminSSEManagerService.connect(Integer.valueOf(userId));
|
||||||
try {
|
try {
|
||||||
sse.send("您已连接");
|
sse.send("您已连接");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package com.nflg.mobilebroken.admin.service.impl;
|
package com.nflg.mobilebroken.admin.service.impl;
|
||||||
|
|
||||||
import com.nflg.mobilebroken.common.constant.Constant;
|
import com.nflg.mobilebroken.common.constant.Constant;
|
||||||
|
import com.nflg.mobilebroken.common.pojo.dto.NotifyDTO;
|
||||||
|
import com.nflg.mobilebroken.common.pojo.dto.SSEMessageDTO;
|
||||||
import com.nflg.mobilebroken.common.pojo.dto.UserDTO;
|
import com.nflg.mobilebroken.common.pojo.dto.UserDTO;
|
||||||
import com.nflg.mobilebroken.starter.service.INotifyPushService;
|
import com.nflg.mobilebroken.starter.service.INotifyPushService;
|
||||||
import com.nflg.mobilebroken.starter.service.SSEManagerService;
|
import com.nflg.mobilebroken.starter.service.SSEManagerService;
|
||||||
|
|
@ -27,7 +29,10 @@ public class SSEINotifyPushService implements INotifyPushService {
|
||||||
@Override
|
@Override
|
||||||
public void push(UserDTO user, String subject, String content) {
|
public void push(UserDTO user, String subject, String content) {
|
||||||
try {
|
try {
|
||||||
sseManagerService.send(user.getId().toString(), subject, content);
|
SSEMessageDTO message = new SSEMessageDTO()
|
||||||
|
.setType(2)
|
||||||
|
.setData(new NotifyDTO().setSubject(subject).setContent(content));
|
||||||
|
sseManagerService.send(user.getId(), message);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("发送SSE失败", e);
|
log.error("发送SSE失败", e);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ public class FileController extends ControllerBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String buildFilePath(String fileName){
|
private String buildFilePath(String fileName){
|
||||||
return StrUtil.format("{}/{}/{}/{}", LocalDateTime.now().format(FORMATTER), AppUserUtil.getUserId(),
|
return StrUtil.format("cfs/{}/{}/{}/{}", LocalDateTime.now().format(FORMATTER), AppUserUtil.getUserId(),
|
||||||
RandomUtil.randomString(4),fileName);
|
RandomUtil.randomString(4),fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
package com.nflg.mobilebroken.cfs.controller;
|
package com.nflg.mobilebroken.cfs.controller;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
||||||
import com.nflg.mobilebroken.common.constant.Constant;
|
import com.nflg.mobilebroken.common.constant.Constant;
|
||||||
import com.nflg.mobilebroken.common.pojo.ApiResult;
|
import com.nflg.mobilebroken.common.pojo.ApiResult;
|
||||||
import com.nflg.mobilebroken.common.pojo.PageData;
|
import com.nflg.mobilebroken.common.pojo.PageData;
|
||||||
|
|
@ -43,11 +41,7 @@ public class MessageController extends ControllerBase {
|
||||||
*/
|
*/
|
||||||
@PostMapping("searchMessages")
|
@PostMapping("searchMessages")
|
||||||
public ApiResult<PageData<AppMessageVO>> searchMessages(@RequestBody AppMessageSearchRequest request) {
|
public ApiResult<PageData<AppMessageVO>> searchMessages(@RequestBody AppMessageSearchRequest request) {
|
||||||
IPage<AppMessageVO> page = new Page<>();
|
return ApiResult.success(appMessageService.search(AppUserUtil.getUserId(), request));
|
||||||
page.setCurrent(request.getPage());
|
|
||||||
page.setSize(request.getPageSize());
|
|
||||||
appMessageService.search(AppUserUtil.getUserId(), request.getTitle(), page);
|
|
||||||
return ApiResult.success(page);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -79,11 +73,7 @@ public class MessageController extends ControllerBase {
|
||||||
*/
|
*/
|
||||||
@GetMapping("getNotReadMessages")
|
@GetMapping("getNotReadMessages")
|
||||||
public ApiResult<PageData<AppMessageVO>> getNotReadMessages(@RequestParam(defaultValue = "10") Integer num) {
|
public ApiResult<PageData<AppMessageVO>> getNotReadMessages(@RequestParam(defaultValue = "10") Integer num) {
|
||||||
IPage<AppMessageVO> page = new Page<>();
|
return ApiResult.success(appMessageService.getNotReadMessage(AppUserUtil.getUserId(), num));
|
||||||
page.setCurrent(1);
|
|
||||||
page.setSize(num);
|
|
||||||
appMessageService.getNotReadMessage(AppUserUtil.getUserId(), num, page);
|
|
||||||
return ApiResult.success(page);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ public class SSEController extends ControllerBase {
|
||||||
private APPSSEManagerService sseManagerService;
|
private APPSSEManagerService sseManagerService;
|
||||||
|
|
||||||
@GetMapping(value = "connect",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
|
@GetMapping(value = "connect",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
|
||||||
public SseEmitter connect(@RequestParam String userId){
|
public SseEmitter connect(@RequestParam Integer userId) {
|
||||||
SseEmitter sse=sseManagerService.connect(userId);
|
SseEmitter sse=sseManagerService.connect(userId);
|
||||||
try {
|
try {
|
||||||
sse.send("您已连接");
|
sse.send("您已连接");
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package com.nflg.mobilebroken.cfs.controller;
|
package com.nflg.mobilebroken.cfs.controller;
|
||||||
|
|
||||||
import com.nflg.mobilebroken.common.pojo.ApiResult;
|
import com.nflg.mobilebroken.common.pojo.ApiResult;
|
||||||
|
import com.nflg.mobilebroken.common.pojo.dto.NotifyDTO;
|
||||||
|
import com.nflg.mobilebroken.common.pojo.dto.SSEMessageDTO;
|
||||||
import com.nflg.mobilebroken.starter.service.impl.APPSSEManagerService;
|
import com.nflg.mobilebroken.starter.service.impl.APPSSEManagerService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
|
@ -21,7 +23,10 @@ public class TestController extends ControllerBase {
|
||||||
|
|
||||||
@GetMapping("sse/send")
|
@GetMapping("sse/send")
|
||||||
public ApiResult<Void> sendSse(@RequestParam String userId, @RequestParam String message) throws IOException {
|
public ApiResult<Void> sendSse(@RequestParam String userId, @RequestParam String message) throws IOException {
|
||||||
sseManagerService.send(userId,"测试消息",message);
|
SSEMessageDTO messageDTO = new SSEMessageDTO()
|
||||||
|
.setType(2)
|
||||||
|
.setData(new NotifyDTO().setSubject("消息测试").setContent("消息内容"));
|
||||||
|
sseManagerService.send(Integer.valueOf(userId), messageDTO);
|
||||||
return ApiResult.success();
|
return ApiResult.success();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,29 +5,38 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.nflg.mobilebroken.common.constant.TicketState;
|
import com.nflg.mobilebroken.common.constant.TicketState;
|
||||||
import com.nflg.mobilebroken.common.pojo.ApiResult;
|
import com.nflg.mobilebroken.common.pojo.ApiResult;
|
||||||
import com.nflg.mobilebroken.common.pojo.PageData;
|
import com.nflg.mobilebroken.common.pojo.PageData;
|
||||||
|
import com.nflg.mobilebroken.common.pojo.dto.ChatMessageDTO;
|
||||||
|
import com.nflg.mobilebroken.common.pojo.dto.SSEMessageDTO;
|
||||||
|
import com.nflg.mobilebroken.common.pojo.dto.TicketChatDTO;
|
||||||
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.AppUserUtil;
|
||||||
import com.nflg.mobilebroken.common.util.MultilingualUtil;
|
import com.nflg.mobilebroken.common.util.MultilingualUtil;
|
||||||
import com.nflg.mobilebroken.common.util.PageUtil;
|
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.impl.APPSSEManagerService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
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.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 工单相关接口
|
* 工单相关接口
|
||||||
* @author 曹鹏飞
|
* @author 曹鹏飞
|
||||||
**/
|
**/
|
||||||
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/ticket")
|
@RequestMapping("/ticket")
|
||||||
//@SaUserCheckLogin
|
//@SaUserCheckLogin
|
||||||
|
|
@ -42,8 +51,6 @@ public class TiketController extends ControllerBase {
|
||||||
@Resource
|
@Resource
|
||||||
private ITicketFollowService ticketFollowService;
|
private ITicketFollowService ticketFollowService;
|
||||||
|
|
||||||
// @Resource
|
|
||||||
// private ITicketChatService ticketChatService;
|
|
||||||
@Resource
|
@Resource
|
||||||
private TicketChatService ticketChatService;
|
private TicketChatService ticketChatService;
|
||||||
|
|
||||||
|
|
@ -68,6 +75,9 @@ public class TiketController extends ControllerBase {
|
||||||
@Resource
|
@Resource
|
||||||
private ITBaseCustomerService customerService;
|
private ITBaseCustomerService customerService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private APPSSEManagerService sseManagerService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 搜索设备
|
* 搜索设备
|
||||||
*
|
*
|
||||||
|
|
@ -108,9 +118,9 @@ public class TiketController extends ControllerBase {
|
||||||
@PostMapping("/addTiket")
|
@PostMapping("/addTiket")
|
||||||
public ApiResult<Void> addTiket(@Valid @RequestBody TicketAddRequest request) {
|
public ApiResult<Void> addTiket(@Valid @RequestBody TicketAddRequest request) {
|
||||||
Integer ticketId = ticketService.add(request, AppUserUtil.getUserId());
|
Integer ticketId = ticketService.add(request, AppUserUtil.getUserId());
|
||||||
ticketChatService.add(new TicketChat()
|
ticketChatService.add(new TicketChatDTO()
|
||||||
.setTicketId(ticketId)
|
.setTicketId(ticketId)
|
||||||
.setMessages(Collections.singletonList(new ChatMessageVO()
|
.setMessages(Collections.singletonList(new ChatMessageDTO()
|
||||||
.setFrom("system")
|
.setFrom("system")
|
||||||
.setSenderId(0)
|
.setSenderId(0)
|
||||||
.setSenderName("服务助手")
|
.setSenderName("服务助手")
|
||||||
|
|
@ -159,15 +169,21 @@ public class TiketController extends ControllerBase {
|
||||||
AppUser user = appUserService.getById(ticket.getUserId());
|
AppUser user = appUserService.getById(ticket.getUserId());
|
||||||
AppArea appArea = appAreaService.getById(user.getAreaId());
|
AppArea appArea = appAreaService.getById(user.getAreaId());
|
||||||
TBaseCustomer company = customerService.getById(Integer.valueOf(user.getCompanyId()));
|
TBaseCustomer company = customerService.getById(Integer.valueOf(user.getCompanyId()));
|
||||||
|
DeviceInfoVO device = deviceService.getByDeviceNo(ticket.getDeviceNo());
|
||||||
TicketInfoVO vo = new TicketInfoVO()
|
TicketInfoVO vo = new TicketInfoVO()
|
||||||
.setId(ticket.getId())
|
.setId(ticket.getId())
|
||||||
.setTitle(ticket.getTitle())
|
.setTitle(ticket.getTitle())
|
||||||
|
.setDeviceNo(ticket.getDeviceNo())
|
||||||
|
.setModelNo(device.getModelNo())
|
||||||
|
.setComponent(ticket.getComponent())
|
||||||
|
.setUseTime(ticket.getUseTime())
|
||||||
.setDescription(ticket.getDescription())
|
.setDescription(ticket.getDescription())
|
||||||
.setState(ticket.getState())
|
.setState(ticket.getState())
|
||||||
.setAttachments(StrUtil.isNotBlank(ticket.getAttachments()) ? StrUtil.split(",", ticket.getAttachments()) : Collections.emptyList())
|
.setAttachments(StrUtil.isNotBlank(ticket.getAttachments()) ? StrUtil.split(",", ticket.getAttachments()) : Collections.emptyList())
|
||||||
.setCreateUserId(ticket.getUserId())
|
.setCreateUserId(ticket.getUserId())
|
||||||
.setCreateUserName(user.getName())
|
.setCreateUserName(user.getName())
|
||||||
.setCreateUserAvatar(user.getAvatar())
|
.setCreateUserAvatar(user.getAvatar())
|
||||||
|
.setCreateTime(ticket.getCreateTime())
|
||||||
.setAreaName(appArea.getName())
|
.setAreaName(appArea.getName())
|
||||||
.setCompanyName(company.getAgencyCompanyName());
|
.setCompanyName(company.getAgencyCompanyName());
|
||||||
return ApiResult.success(vo);
|
return ApiResult.success(vo);
|
||||||
|
|
@ -179,7 +195,7 @@ public class TiketController extends ControllerBase {
|
||||||
* @return 聊天记录
|
* @return 聊天记录
|
||||||
**/
|
**/
|
||||||
@GetMapping("getChatMessages")
|
@GetMapping("getChatMessages")
|
||||||
public ApiResult<List<ChatMessageVO>> getChatMessages(@Valid @RequestParam @NotNull Integer ticketId) {
|
public ApiResult<List<ChatMessageDTO>> getChatMessages(@Valid @RequestParam @NotNull Integer ticketId) {
|
||||||
return ApiResult.success(ticketChatService.getMessages(ticketId));
|
return ApiResult.success(ticketChatService.getMessages(ticketId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -189,10 +205,17 @@ public class TiketController extends ControllerBase {
|
||||||
**/
|
**/
|
||||||
@PostMapping("addChatMessage")
|
@PostMapping("addChatMessage")
|
||||||
public ApiResult<Void> addChatMessage(@Valid @RequestBody AddChatMessageRequest request){
|
public ApiResult<Void> addChatMessage(@Valid @RequestBody AddChatMessageRequest request){
|
||||||
ChatMessageVO message = new ChatMessageVO()
|
Ticket ticket = ticketService.getById(request.getTicketId());
|
||||||
|
VUtils.trueThrowBusinessError(Objects.isNull(ticket)).throwMessage("工单不存在");
|
||||||
|
VUtils.trueThrowBusinessError(Objects.equals(ticket.getState(), TicketState.Revoked.getState())
|
||||||
|
|| Objects.equals(ticket.getState(), TicketState.Closed.getState()))
|
||||||
|
.throwMessage("当前工单状态不允许发送消息");
|
||||||
|
AppUser user = appUserService.getById(AppUserUtil.getUserId());
|
||||||
|
ChatMessageDTO message = new ChatMessageDTO()
|
||||||
.setFrom("app")
|
.setFrom("app")
|
||||||
.setSenderId(AppUserUtil.getUserId())
|
.setSenderId(user.getId())
|
||||||
.setSenderName(AppUserUtil.getUserName())
|
.setSenderName(user.getName())
|
||||||
|
.setSenderAvatar(user.getAvatar())
|
||||||
.setContent(request.getContent())
|
.setContent(request.getContent())
|
||||||
.setCreateTime(Instant.now())
|
.setCreateTime(Instant.now())
|
||||||
.setAttachments(request.getAttachments());
|
.setAttachments(request.getAttachments());
|
||||||
|
|
@ -201,6 +224,20 @@ public class TiketController extends ControllerBase {
|
||||||
// chat.getMessages().add(message);
|
// chat.getMessages().add(message);
|
||||||
// ticketChatService.save(chat);
|
// ticketChatService.save(chat);
|
||||||
ticketChatService.addMessage(request.getTicketId(), message);
|
ticketChatService.addMessage(request.getTicketId(), message);
|
||||||
|
//推送消息
|
||||||
|
String handle = ticket.getHandle();
|
||||||
|
if (StrUtil.isNotBlank(handle)) {
|
||||||
|
SSEMessageDTO messageDTO = new SSEMessageDTO()
|
||||||
|
.setType(1)
|
||||||
|
.setData(message);
|
||||||
|
StrUtil.split(handle, ",").forEach(userId -> {
|
||||||
|
try {
|
||||||
|
sseManagerService.send(Integer.valueOf(userId), messageDTO);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("发送SSE消息出错", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
return ApiResult.success();
|
return ApiResult.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,10 @@
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-web</artifactId>
|
<artifactId>spring-web</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.data</groupId>
|
||||||
|
<artifactId>spring-data-mongodb</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,18 @@
|
||||||
package com.nflg.mobilebroken.common.pojo.vo;
|
package com.nflg.mobilebroken.common.pojo.dto;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
import org.springframework.data.annotation.Id;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
public class ChatMessageVO {
|
public class ChatMessageDTO {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private String id;
|
||||||
|
|
||||||
//来源
|
//来源
|
||||||
private String from;
|
private String from;
|
||||||
|
|
@ -19,6 +23,9 @@ public class ChatMessageVO {
|
||||||
// 发送者名称
|
// 发送者名称
|
||||||
private String senderName;
|
private String senderName;
|
||||||
|
|
||||||
|
// 发送者头像
|
||||||
|
private String senderAvatar;
|
||||||
|
|
||||||
// 消息内容
|
// 消息内容
|
||||||
private String content;
|
private String content;
|
||||||
|
|
||||||
|
|
@ -29,5 +36,5 @@ public class ChatMessageVO {
|
||||||
private Instant createTime;
|
private Instant createTime;
|
||||||
|
|
||||||
// 引用的消息
|
// 引用的消息
|
||||||
private ChatMessageVO quote;
|
private ChatMessageDTO quote;
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.nflg.mobilebroken.common.pojo.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class NotifyDTO {
|
||||||
|
|
||||||
|
private String subject;
|
||||||
|
|
||||||
|
private String content;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.nflg.mobilebroken.common.pojo.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class SSEMessageDTO {
|
||||||
|
|
||||||
|
//类型,1:工单会话消息,2:消息提醒
|
||||||
|
private int type;
|
||||||
|
|
||||||
|
//消息内容
|
||||||
|
private Object data;
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package com.nflg.mobilebroken.repository.entity;
|
package com.nflg.mobilebroken.common.pojo.dto;
|
||||||
|
|
||||||
import com.nflg.mobilebroken.common.pojo.vo.ChatMessageVO;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
import org.springframework.data.annotation.Id;
|
import org.springframework.data.annotation.Id;
|
||||||
|
|
@ -12,12 +11,12 @@ import java.util.List;
|
||||||
@Data
|
@Data
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
@Document(collection = "TicketChat")
|
@Document(collection = "TicketChat")
|
||||||
public class TicketChat {
|
public class TicketChatDTO {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
private String id;
|
private String id;
|
||||||
|
|
||||||
private Integer ticketId;
|
private Integer ticketId;
|
||||||
|
|
||||||
private List<ChatMessageVO> messages = new ArrayList<>();
|
private List<ChatMessageDTO> messages = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.nflg.mobilebroken.common.pojo.request;
|
package com.nflg.mobilebroken.common.pojo.request;
|
||||||
|
|
||||||
import com.nflg.mobilebroken.common.pojo.vo.ChatMessageVO;
|
import com.nflg.mobilebroken.common.pojo.dto.ChatMessageDTO;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import javax.validation.constraints.NotBlank;
|
import javax.validation.constraints.NotBlank;
|
||||||
|
|
@ -22,5 +22,5 @@ public class AddChatMessageRequest {
|
||||||
private List<String> attachments;
|
private List<String> attachments;
|
||||||
|
|
||||||
// 引用的消息
|
// 引用的消息
|
||||||
private ChatMessageVO quote;
|
private ChatMessageDTO quote;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ import java.time.LocalDateTime;
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
public class AppMessageVO {
|
public class AppMessageVO {
|
||||||
|
|
||||||
|
private int id;
|
||||||
|
|
||||||
//工单id
|
//工单id
|
||||||
private int ticketId;
|
private int ticketId;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package com.nflg.mobilebroken.common.pojo.vo;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
|
@ -27,6 +28,9 @@ public class TicketInfoVO {
|
||||||
//创建人头像
|
//创建人头像
|
||||||
private String createUserAvatar;
|
private String createUserAvatar;
|
||||||
|
|
||||||
|
//提交时间
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
//工单状态
|
//工单状态
|
||||||
private Byte state;
|
private Byte state;
|
||||||
|
|
||||||
|
|
@ -36,6 +40,18 @@ public class TicketInfoVO {
|
||||||
//所属区域
|
//所属区域
|
||||||
private String areaName;
|
private String areaName;
|
||||||
|
|
||||||
|
//设备编号
|
||||||
|
private String deviceNo;
|
||||||
|
|
||||||
|
//设备机型
|
||||||
|
private String modelNo;
|
||||||
|
|
||||||
|
//问题部位
|
||||||
|
private String component;
|
||||||
|
|
||||||
|
//使用时长,单位: 小时
|
||||||
|
private Integer useTime;
|
||||||
|
|
||||||
//附件
|
//附件
|
||||||
private List<String> attachments;
|
private List<String> attachments;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,14 @@ package com.nflg.mobilebroken.repository.entity;
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import java.io.Serializable;
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* 用户端-用户
|
* 用户端-用户
|
||||||
|
|
@ -85,9 +86,9 @@ public class AppUser implements Serializable {
|
||||||
private Boolean isPrimary;
|
private Boolean isPrimary;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 职位编码
|
* 职位id
|
||||||
*/
|
*/
|
||||||
private String titleCode;
|
private Integer titleId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 所属销售代表
|
* 所属销售代表
|
||||||
|
|
|
||||||
|
|
@ -75,9 +75,9 @@ public class AppUserApplyfor implements Serializable {
|
||||||
private Byte type;
|
private Byte type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 职位编码
|
* 职位id
|
||||||
*/
|
*/
|
||||||
private String titleCode;
|
private Integer titleId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理状态,0:待审核,1:审核通过,2:审核不通过
|
* 处理状态,0:待审核,1:审核通过,2:审核不通过
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ import com.nflg.mobilebroken.repository.entity.AppMessage;
|
||||||
*/
|
*/
|
||||||
public interface AppMessageMapper extends BaseMapper<AppMessage> {
|
public interface AppMessageMapper extends BaseMapper<AppMessage> {
|
||||||
|
|
||||||
void getNotReadMessage(Integer userId, Integer num, IPage<AppMessageVO> page);
|
IPage<AppMessageVO> getNotReadMessage(Integer userId, Integer num, IPage<AppMessageVO> page);
|
||||||
|
|
||||||
void search(Integer userId, String title, IPage<AppMessageVO> page);
|
IPage<AppMessageVO> search(Integer userId, String title, IPage<AppMessageVO> page);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.nflg.mobilebroken.repository.service;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.nflg.mobilebroken.common.pojo.request.AppMessageSearchRequest;
|
||||||
import com.nflg.mobilebroken.common.pojo.vo.AppMessageVO;
|
import com.nflg.mobilebroken.common.pojo.vo.AppMessageVO;
|
||||||
import com.nflg.mobilebroken.repository.entity.AppMessage;
|
import com.nflg.mobilebroken.repository.entity.AppMessage;
|
||||||
|
|
||||||
|
|
@ -17,9 +18,9 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
public interface IAppMessageService extends IService<AppMessage> {
|
public interface IAppMessageService extends IService<AppMessage> {
|
||||||
|
|
||||||
void getNotReadMessage(Integer userId, Integer num, IPage<AppMessageVO> page);
|
IPage<AppMessageVO> getNotReadMessage(Integer userId, Integer num);
|
||||||
|
|
||||||
void search(Integer userId, String title, IPage<AppMessageVO> page);
|
IPage<AppMessageVO> search(Integer userId, AppMessageSearchRequest request);
|
||||||
|
|
||||||
void setReaded(List<Integer> ids);
|
void setReaded(List<Integer> ids);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
package com.nflg.mobilebroken.repository.service;
|
|
||||||
|
|
||||||
import com.nflg.mobilebroken.common.pojo.vo.ChatMessageVO;
|
|
||||||
import com.nflg.mobilebroken.repository.entity.TicketChat;
|
|
||||||
import org.apache.ibatis.annotations.Update;
|
|
||||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
|
||||||
import org.springframework.data.mongodb.repository.Query;
|
|
||||||
|
|
||||||
public interface ITicketChatService extends MongoRepository<TicketChat, String> {
|
|
||||||
|
|
||||||
@Query("{ 'ticketId': ?0 }")
|
|
||||||
TicketChat findByTicketId(Integer ticketId);
|
|
||||||
|
|
||||||
@Query("{ 'ticketId': ?0 }")
|
|
||||||
@Update("{ '$push': { 'messages': ?1 } }")
|
|
||||||
void pushMessage(Integer ticketId, ChatMessageVO message);
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package com.nflg.mobilebroken.repository.service;
|
package com.nflg.mobilebroken.repository.service;
|
||||||
|
|
||||||
import com.nflg.mobilebroken.common.pojo.vo.ChatMessageVO;
|
import com.nflg.mobilebroken.common.pojo.dto.ChatMessageDTO;
|
||||||
import com.nflg.mobilebroken.repository.entity.TicketChat;
|
import com.nflg.mobilebroken.common.pojo.dto.TicketChatDTO;
|
||||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||||
import org.springframework.data.mongodb.core.query.Criteria;
|
import org.springframework.data.mongodb.core.query.Criteria;
|
||||||
import org.springframework.data.mongodb.core.query.Query;
|
import org.springframework.data.mongodb.core.query.Query;
|
||||||
|
|
@ -19,26 +19,26 @@ public class TicketChatService {
|
||||||
@Resource
|
@Resource
|
||||||
private MongoTemplate mongoTemplate;
|
private MongoTemplate mongoTemplate;
|
||||||
|
|
||||||
public void add(TicketChat ticketChat) {
|
public void add(TicketChatDTO ticketChatDTO) {
|
||||||
mongoTemplate.save(ticketChat);
|
mongoTemplate.save(ticketChatDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ChatMessageVO> getMessages(Integer ticketId) {
|
public List<ChatMessageDTO> getMessages(Integer ticketId) {
|
||||||
Query query = new Query(Criteria.where("ticketId").is(ticketId));
|
Query query = new Query(Criteria.where("ticketId").is(ticketId));
|
||||||
TicketChat ticketChat = mongoTemplate.findOne(query, TicketChat.class);
|
TicketChatDTO ticketChatDTO = mongoTemplate.findOne(query, TicketChatDTO.class);
|
||||||
if (Objects.isNull(ticketChat)) {
|
if (Objects.isNull(ticketChatDTO)) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
} else {
|
} else {
|
||||||
return ticketChat.getMessages();
|
return ticketChatDTO.getMessages();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addMessage(Integer ticketId, ChatMessageVO newMessage) {
|
public void addMessage(Integer ticketId, ChatMessageDTO newMessage) {
|
||||||
// 创建查询条件,查找 ticketId = ticketId 的 TicketChat
|
// 创建查询条件,查找 ticketId = ticketId 的 TicketChat
|
||||||
Query query = new Query(Criteria.where("ticketId").is(ticketId));
|
Query query = new Query(Criteria.where("ticketId").is(ticketId));
|
||||||
// 创建更新操作,向 messages 列表中添加新消息
|
// 创建更新操作,向 messages 列表中添加新消息
|
||||||
Update update = new Update().push("messages", newMessage);
|
Update update = new Update().push("messages", newMessage);
|
||||||
// 执行更新操作
|
// 执行更新操作
|
||||||
mongoTemplate.findAndModify(query, update, TicketChat.class);
|
mongoTemplate.findAndModify(query, update, TicketChatDTO.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
package com.nflg.mobilebroken.repository.service.impl;
|
package com.nflg.mobilebroken.repository.service.impl;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.nflg.mobilebroken.common.pojo.request.AppMessageSearchRequest;
|
||||||
import com.nflg.mobilebroken.common.pojo.vo.AppMessageVO;
|
import com.nflg.mobilebroken.common.pojo.vo.AppMessageVO;
|
||||||
import com.nflg.mobilebroken.repository.entity.AppMessage;
|
import com.nflg.mobilebroken.repository.entity.AppMessage;
|
||||||
import com.nflg.mobilebroken.repository.mapper.AppMessageMapper;
|
import com.nflg.mobilebroken.repository.mapper.AppMessageMapper;
|
||||||
|
|
@ -22,13 +24,13 @@ import java.util.List;
|
||||||
public class AppMessageServiceImpl extends ServiceImpl<AppMessageMapper, AppMessage> implements IAppMessageService {
|
public class AppMessageServiceImpl extends ServiceImpl<AppMessageMapper, AppMessage> implements IAppMessageService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getNotReadMessage(Integer userId, Integer num, IPage<AppMessageVO> page) {
|
public IPage<AppMessageVO> getNotReadMessage(Integer userId, Integer num) {
|
||||||
baseMapper.getNotReadMessage(userId, num, page);
|
return baseMapper.getNotReadMessage(userId, num, new Page<>(1, num));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void search(Integer userId, String title, IPage<AppMessageVO> page) {
|
public IPage<AppMessageVO> search(Integer userId, AppMessageSearchRequest request) {
|
||||||
baseMapper.search(userId,title,page);
|
return baseMapper.search(userId, request.getTitle(), new Page<>(request.getPage(), request.getPageSize()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ public class AppUserApplyforServiceImpl extends ServiceImpl<AppUserApplyforMappe
|
||||||
.setState(AppUserApplyForState.PENDINGAPPROVAL.getState().byteValue())
|
.setState(AppUserApplyForState.PENDINGAPPROVAL.getState().byteValue())
|
||||||
.setAreaId(request.getAreaId())
|
.setAreaId(request.getAreaId())
|
||||||
.setCompanyId(request.getCompanyId())
|
.setCompanyId(request.getCompanyId())
|
||||||
|
.setTitleId(request.getTitleId())
|
||||||
.setType(AppUserApplyforType.ADD.getState().byteValue())
|
.setType(AppUserApplyforType.ADD.getState().byteValue())
|
||||||
.setCreateBy(AdminUserUtil.getUserId())
|
.setCreateBy(AdminUserUtil.getUserId())
|
||||||
.setCreateTime(LocalDateTime.now());
|
.setCreateTime(LocalDateTime.now());
|
||||||
|
|
@ -99,10 +100,7 @@ public class AppUserApplyforServiceImpl extends ServiceImpl<AppUserApplyforMappe
|
||||||
VUtils.trueThrowBusinessError(Objects.isNull(applyfor)).throwMessage("审批信息不存在");
|
VUtils.trueThrowBusinessError(Objects.isNull(applyfor)).throwMessage("审批信息不存在");
|
||||||
AppUserApplyforVO vo = new AppUserApplyforVO();
|
AppUserApplyforVO vo = new AppUserApplyforVO();
|
||||||
AppArea area = appAreaService.getById(applyfor.getAreaId());
|
AppArea area = appAreaService.getById(applyfor.getAreaId());
|
||||||
TBasePosition position = positionService.lambdaQuery()
|
TBasePosition position = positionService.getById(applyfor.getTitleId());
|
||||||
.eq(TBasePosition::getDataValidState, 1)
|
|
||||||
.eq(TBasePosition::getPositionCode, applyfor.getTitleCode())
|
|
||||||
.one();
|
|
||||||
String titleName = Objects.isNull(position) ? "" : position.getPositionName();
|
String titleName = Objects.isNull(position) ? "" : position.getPositionName();
|
||||||
vo.setApplyfor(new AppUserApplyforInfoVO()
|
vo.setApplyfor(new AppUserApplyforInfoVO()
|
||||||
.setAreaName(area.getName())
|
.setAreaName(area.getName())
|
||||||
|
|
@ -141,7 +139,7 @@ public class AppUserApplyforServiceImpl extends ServiceImpl<AppUserApplyforMappe
|
||||||
.setPassword(PASSWORDENCODER.encode(request.getPassword()))
|
.setPassword(PASSWORDENCODER.encode(request.getPassword()))
|
||||||
.setAreaId(applyfor.getAreaId())
|
.setAreaId(applyfor.getAreaId())
|
||||||
.setCompanyId(String.valueOf(applyfor.getCompanyId()))
|
.setCompanyId(String.valueOf(applyfor.getCompanyId()))
|
||||||
.setTitleCode(applyfor.getTitleCode())
|
.setTitleId(applyfor.getTitleId())
|
||||||
.setEnable(true)
|
.setEnable(true)
|
||||||
.setCreateBy(applyfor.getCreateBy())
|
.setCreateBy(applyfor.getCreateBy())
|
||||||
.setCreateTime(LocalDateTime.now())
|
.setCreateTime(LocalDateTime.now())
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
<mapper namespace="com.nflg.mobilebroken.repository.mapper.AppMessageMapper">
|
<mapper namespace="com.nflg.mobilebroken.repository.mapper.AppMessageMapper">
|
||||||
|
|
||||||
<select id="getNotReadMessage">
|
<select id="getNotReadMessage" resultType="com.nflg.mobilebroken.common.pojo.vo.AppMessageVO">
|
||||||
SELECT t.id AS 'ticketId',t.`no` AS 'ticketNo',t.title AS 'ticketTitle',m.content,m.create_time AS 'createTime',u.`name` AS 'ticketCreateBy',t.create_time AS 'ticketCreateTime',t.handle AS 'ticketHandleBy',m.is_read AS 'isRead'
|
SELECT t.id AS 'ticketId',t.`no` AS 'ticketNo',t.title AS 'ticketTitle',m.content,m.create_time AS 'createTime',u.`name` AS 'ticketCreateBy',t.create_time AS 'ticketCreateTime',t.handle AS 'ticketHandleBy',m.is_read AS 'isRead'
|
||||||
FROM app_message m
|
FROM app_message m
|
||||||
INNER JOIN ticket t ON m.ticket_id=t.id
|
INNER JOIN ticket t ON m.ticket_id=t.id
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
WHERE m.is_read=0 AND m.user_id=#{userId}
|
WHERE m.is_read=0 AND m.user_id=#{userId}
|
||||||
ORDER BY m.id
|
ORDER BY m.id
|
||||||
</select>
|
</select>
|
||||||
<select id="search">
|
<select id="search" resultType="com.nflg.mobilebroken.common.pojo.vo.AppMessageVO">
|
||||||
SELECT t.id AS 'ticketId',t.`no` AS 'ticketNo',t.title AS 'ticketTitle',m.content,m.create_time AS 'createTime',u.`name` AS 'ticketCreateBy',t.create_time AS 'ticketCreateTime',t.handle AS 'ticketHandleBy',m.is_read AS 'isRead'
|
SELECT t.id AS 'ticketId',t.`no` AS 'ticketNo',t.title AS 'ticketTitle',m.content,m.create_time AS 'createTime',u.`name` AS 'ticketCreateBy',t.create_time AS 'ticketCreateTime',t.handle AS 'ticketHandleBy',m.is_read AS 'isRead'
|
||||||
FROM app_message m
|
FROM app_message m
|
||||||
INNER JOIN ticket t ON m.ticket_id=t.id
|
INNER JOIN ticket t ON m.ticket_id=t.id
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,25 @@ public class SSEManagerBase {
|
||||||
VUtils.trueThrow(IS_SHUTDOWN).throwMessage(STATE.ServiceConnectRefused,"SSE服务已关闭");
|
VUtils.trueThrow(IS_SHUTDOWN).throwMessage(STATE.ServiceConnectRefused,"SSE服务已关闭");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected SseEmitter connect(String userId, Map<String, SseEmitter> emitters){
|
protected static void shutdown(Map<Integer, SseEmitter> emitters) {
|
||||||
|
IS_SHUTDOWN=true;
|
||||||
|
log.warn("准备关闭SSE服务");
|
||||||
|
emitters.forEach((k,v)->{
|
||||||
|
try {
|
||||||
|
v.send("因SSE服务关闭,连接即将断开");
|
||||||
|
}catch (Exception ex){
|
||||||
|
log.error("SSE发送消息失败:"+k,ex);
|
||||||
|
}
|
||||||
|
v.complete();
|
||||||
|
});
|
||||||
|
log.warn("SSE服务已关闭");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void close(SseEmitter emitter){
|
||||||
|
emitter.complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected SseEmitter connect(Integer userId, Map<Integer, SseEmitter> emitters) {
|
||||||
SseEmitter emitter = new SseEmitter(Long.MAX_VALUE);
|
SseEmitter emitter = new SseEmitter(Long.MAX_VALUE);
|
||||||
emitters.put(userId, emitter);
|
emitters.put(userId, emitter);
|
||||||
emitter.onError((ex) -> {
|
emitter.onError((ex) -> {
|
||||||
|
|
@ -41,27 +59,9 @@ public class SSEManagerBase {
|
||||||
return emitter;
|
return emitter;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void close(SseEmitter emitter){
|
protected void send(Object message, SseEmitter emitter) throws IOException {
|
||||||
emitter.complete();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static void shutdown(Map<String, SseEmitter> emitters){
|
|
||||||
IS_SHUTDOWN=true;
|
|
||||||
log.warn("准备关闭SSE服务");
|
|
||||||
emitters.forEach((k,v)->{
|
|
||||||
try {
|
|
||||||
v.send("因SSE服务关闭,连接即将断开");
|
|
||||||
}catch (Exception ex){
|
|
||||||
log.error("SSE发送消息失败:"+k,ex);
|
|
||||||
}
|
|
||||||
v.complete();
|
|
||||||
});
|
|
||||||
log.warn("SSE服务已关闭");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void send(String subject, String message,SseEmitter emitter) throws IOException {
|
|
||||||
VUtils.trueThrowBusinessError(Objects.isNull(emitter)).throwMessage("没有找到sse");
|
VUtils.trueThrowBusinessError(Objects.isNull(emitter)).throwMessage("没有找到sse");
|
||||||
log.error("没有找到sse: ");
|
log.error("没有找到sse: ");
|
||||||
emitter.send(subject+":"+message);
|
emitter.send(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,17 @@
|
||||||
package com.nflg.mobilebroken.starter.service;
|
package com.nflg.mobilebroken.starter.service;
|
||||||
|
|
||||||
|
import com.nflg.mobilebroken.common.pojo.dto.SSEMessageDTO;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public interface SSEManagerService {
|
public interface SSEManagerService {
|
||||||
|
|
||||||
SseEmitter connect(String userId);
|
SseEmitter connect(Integer userId);
|
||||||
|
|
||||||
void send(String userId,String subject, String message) throws IOException;
|
void send(Integer userId, SSEMessageDTO message) throws IOException;
|
||||||
|
|
||||||
void close(String userId);
|
void close(Integer userId);
|
||||||
|
|
||||||
void shutdown();
|
void shutdown();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.nflg.mobilebroken.starter.service.impl;
|
package com.nflg.mobilebroken.starter.service.impl;
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.nflg.mobilebroken.common.pojo.dto.SSEMessageDTO;
|
||||||
import com.nflg.mobilebroken.starter.service.SSEManagerBase;
|
import com.nflg.mobilebroken.starter.service.SSEManagerBase;
|
||||||
import com.nflg.mobilebroken.starter.service.SSEManagerService;
|
import com.nflg.mobilebroken.starter.service.SSEManagerService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
@ -16,28 +17,28 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class APPSSEManagerService extends SSEManagerBase implements SSEManagerService {
|
public class APPSSEManagerService extends SSEManagerBase implements SSEManagerService {
|
||||||
|
|
||||||
public static final Map<String, SseEmitter> EMITTERS = new ConcurrentHashMap<>();
|
public static final Map<Integer, SseEmitter> EMITTERS = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SseEmitter connect(String userId) {
|
public SseEmitter connect(Integer userId) {
|
||||||
check();
|
check();
|
||||||
log.info("APP端SSE已连接:"+userId);
|
log.info("APP端SSE已连接:"+userId);
|
||||||
return connect(userId,EMITTERS);
|
return connect(userId,EMITTERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void send(String userId, String subject, String message) throws IOException {
|
public void send(Integer userId, SSEMessageDTO message) throws IOException {
|
||||||
log.info(StrUtil.format("APP端SSE发送消息,用户id: {},标题: {},内容: {}", userId, subject, message));
|
log.info(StrUtil.format("APP端SSE发送消息,用户id: {},内容: {}", userId, message));
|
||||||
SseEmitter emitter = EMITTERS.get(userId);
|
SseEmitter emitter = EMITTERS.get(userId);
|
||||||
if (Objects.isNull(emitter)) {
|
if (Objects.isNull(emitter)) {
|
||||||
log.error("用户未连接SSE: " + userId);
|
log.error("用户未连接SSE: " + userId);
|
||||||
} else {
|
} else {
|
||||||
send(subject, message, emitter);
|
send(message, emitter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close(String userId) {
|
public void close(Integer userId) {
|
||||||
log.info("APP端SSE连接主动关闭:"+userId);
|
log.info("APP端SSE连接主动关闭:"+userId);
|
||||||
close(EMITTERS.remove(userId));
|
close(EMITTERS.remove(userId));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.nflg.mobilebroken.starter.service.impl;
|
package com.nflg.mobilebroken.starter.service.impl;
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.nflg.mobilebroken.common.pojo.dto.SSEMessageDTO;
|
||||||
import com.nflg.mobilebroken.starter.service.SSEManagerBase;
|
import com.nflg.mobilebroken.starter.service.SSEManagerBase;
|
||||||
import com.nflg.mobilebroken.starter.service.SSEManagerService;
|
import com.nflg.mobilebroken.starter.service.SSEManagerService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
@ -16,28 +17,28 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class AdminSSEManagerService extends SSEManagerBase implements SSEManagerService {
|
public class AdminSSEManagerService extends SSEManagerBase implements SSEManagerService {
|
||||||
|
|
||||||
protected static final Map<String, SseEmitter> EMITTERS = new ConcurrentHashMap<>();
|
protected static final Map<Integer, SseEmitter> EMITTERS = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SseEmitter connect(String userId) {
|
public SseEmitter connect(Integer userId) {
|
||||||
check();
|
check();
|
||||||
log.info("管理端SSE已连接:"+userId);
|
log.info("管理端SSE已连接:"+userId);
|
||||||
return connect(userId,EMITTERS);
|
return connect(userId,EMITTERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void send(String userId, String subject, String message) throws IOException {
|
public void send(Integer userId, SSEMessageDTO message) throws IOException {
|
||||||
log.info(StrUtil.format("管理端端SSE发送消息,用户id: {},标题: {},内容: {}", userId, subject, message));
|
log.info(StrUtil.format("管理端端SSE发送消息,用户id: {},内容: {}", userId, message));
|
||||||
SseEmitter emitter = EMITTERS.get(userId);
|
SseEmitter emitter = EMITTERS.get(userId);
|
||||||
if (Objects.isNull(emitter)) {
|
if (Objects.isNull(emitter)) {
|
||||||
log.error("用户未连接SSE: " + userId);
|
log.error("用户未连接SSE: " + userId);
|
||||||
} else {
|
} else {
|
||||||
send(subject, message, emitter);
|
send(message, emitter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close(String userId) {
|
public void close(Integer userId) {
|
||||||
close(EMITTERS.remove(userId));
|
close(EMITTERS.remove(userId));
|
||||||
log.info("管理端SSE连接主动关闭:"+userId);
|
log.info("管理端SSE连接主动关闭:"+userId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue