Commit 2efe91c863b309e4f20bf4270667f84fe29ba537

Authored by 房远帅
1 parent 4494f710

采购-供应商报价看板:供应商报价项目看板已结束实时推送服务

... ... @@ -3,6 +3,7 @@ package com.lframework.xingyun.sc.listeners.app;
3 3 import com.lframework.xingyun.sc.events.quotation.CommonChangedEvent;
4 4 import com.lframework.xingyun.sc.procurement.impl.quotation.SupplierQuotationProjectQuoteServiceImpl;
5 5 import com.lframework.xingyun.sc.procurement.impl.quotation.SupplierQuotationProjectServiceImpl;
  6 +import com.lframework.xingyun.sc.procurement.websocket.quotation.project.SupplierQuotationProjectFinishedRealtimePushService;
6 7 import com.lframework.xingyun.sc.procurement.websocket.quotation.project.SupplierQuotationProjectRealtimePushService;
7 8 import javax.annotation.Resource;
8 9 import org.springframework.stereotype.Component;
... ... @@ -17,6 +18,8 @@ public class SupplierQuotationProjectRealtimeListener {
17 18
18 19 @Resource
19 20 private SupplierQuotationProjectRealtimePushService realtimePushService;
  21 + @Resource
  22 + private SupplierQuotationProjectFinishedRealtimePushService finishedRealtimePushService;
20 23
21 24 /**
22 25 * 报价项目或供应商报价变更后,广播当日完整看板数据
... ... @@ -30,5 +33,6 @@ public class SupplierQuotationProjectRealtimeListener {
30 33 return;
31 34 }
32 35 realtimePushService.broadcastCurrentDayFullData(event.getEventType());
  36 + finishedRealtimePushService.broadcastCurrentDayFinishedData(event.getEventType());
33 37 }
34 38 }
... ...
... ... @@ -14,6 +14,8 @@ import com.lframework.xingyun.sc.procurement.vo.quotation.UpdateSupplierQuotatio
14 14 import io.swagger.annotations.Api;
15 15 import io.swagger.annotations.ApiImplicitParam;
16 16 import io.swagger.annotations.ApiOperation;
  17 +import java.time.LocalDate;
  18 +import java.util.List;
17 19 import javax.annotation.Resource;
18 20 import javax.validation.Valid;
19 21 import javax.validation.constraints.NotBlank;
... ... @@ -63,6 +65,14 @@ public class SupplierQuotationProjectController extends DefaultBaseController {
63 65 return InvokeResultBuilder.success(data);
64 66 }
65 67
  68 + @ApiOperation("当日已完成/已中止项目实时查询")
  69 + @HasPermission({"procure-manage:supplier-price:query"})
  70 + @GetMapping("/queryCurrentDayFinished")
  71 + public InvokeResult<List<SupplierQuotationProject>> queryCurrentDayFinished() {
  72 + return InvokeResultBuilder.success(
  73 + supplierQuotationProjectService.queryCurrentDayFinishedBoardList(LocalDate.now(), getCurrentUser().getId()));
  74 + }
  75 +
66 76 @ApiOperation("修改")
67 77 @HasPermission({"procure-manage:supplier-price:modify"})
68 78 @PutMapping
... ...
... ... @@ -96,6 +96,20 @@ public class SupplierQuotationProjectServiceImpl
96 96 }
97 97
98 98 @Override
  99 + public List<SupplierQuotationProject> queryCurrentDayFinishedBoardList(LocalDate day, String userId) {
  100 + List<SupplierQuotationProject> datas = getBaseMapper().queryCurrentDayFinishedList(day);
  101 + fillComputedStatus(datas);
  102 + if (datas == null || datas.isEmpty()) {
  103 + return datas;
  104 + }
  105 + for (SupplierQuotationProject data : datas) {
  106 + List<SupplierQuotationProjectQuote> quoteList = supplierQuotationProjectQuoteService.listByProject(data.getId(), userId);
  107 + data.setSupplierQuotationProjectQuoteList(quoteList);
  108 + }
  109 + return datas;
  110 + }
  111 +
  112 + @Override
99 113 public SupplierQuotationProject findById(String id) {
100 114 SupplierQuotationProject data = getBaseMapper().findById(id);
101 115 if (data != null) {
... ...
... ... @@ -16,5 +16,7 @@ public interface SupplierQuotationProjectMapper extends BaseMapper<SupplierQuota
16 16 String getMaxCodeByDay(@Param("dayPrefix") String dayPrefix);
17 17
18 18 List<SupplierQuotationProject> queryCurrentDayList(@Param("day") LocalDate day);
  19 +
  20 + List<SupplierQuotationProject> queryCurrentDayFinishedList(@Param("day") LocalDate day);
19 21 }
20 22
... ...
... ... @@ -25,6 +25,8 @@ public interface SupplierQuotationProjectService extends BaseMpService<SupplierQ
25 25
26 26 List<SupplierQuotationProject> queryCurrentDayBoardList(LocalDate day, String userId);
27 27
  28 + List<SupplierQuotationProject> queryCurrentDayFinishedBoardList(LocalDate day, String userId);
  29 +
28 30 /**
29 31 * 更新项目状态
30 32 *
... ...
  1 +package com.lframework.xingyun.sc.procurement.websocket.quotation.project;
  2 +
  3 +import com.lframework.starter.web.core.utils.JsonUtil;
  4 +import com.lframework.xingyun.sc.procurement.dto.quotation.SupplierQuotationProjectRealtimeMessage;
  5 +import com.lframework.xingyun.sc.procurement.entity.SupplierQuotationProject;
  6 +import com.lframework.xingyun.sc.procurement.service.quotation.SupplierQuotationProjectService;
  7 +import java.io.IOException;
  8 +import java.time.LocalDate;
  9 +import java.time.LocalDateTime;
  10 +import java.util.List;
  11 +import java.util.Map;
  12 +import java.util.concurrent.ConcurrentHashMap;
  13 +import javax.annotation.Resource;
  14 +import lombok.extern.slf4j.Slf4j;
  15 +import org.apache.commons.lang3.StringUtils;
  16 +import org.springframework.stereotype.Service;
  17 +import org.springframework.web.socket.TextMessage;
  18 +import org.springframework.web.socket.WebSocketSession;
  19 +
  20 +@Slf4j
  21 +@Service
  22 +public class SupplierQuotationProjectFinishedRealtimePushService {
  23 +
  24 + private final Map<String, WebSocketSession> sessionMap = new ConcurrentHashMap<>();
  25 +
  26 + @Resource
  27 + private SupplierQuotationProjectService supplierQuotationProjectService;
  28 +
  29 + public void register(WebSocketSession session) {
  30 + sessionMap.put(session.getId(), session);
  31 + }
  32 +
  33 + public void unregister(WebSocketSession session) {
  34 + if (session != null) {
  35 + sessionMap.remove(session.getId());
  36 + }
  37 + }
  38 +
  39 + public void broadcastCurrentDayFinishedData(String eventType) {
  40 + if (sessionMap.isEmpty()) {
  41 + return;
  42 + }
  43 +
  44 + for (WebSocketSession session : sessionMap.values()) {
  45 + replayCurrentDayFinishedData(session, eventType);
  46 + }
  47 + }
  48 +
  49 + public void replayCurrentDayFinishedData(WebSocketSession session, String eventType) {
  50 + if (session == null) {
  51 + return;
  52 + }
  53 + sendMessage(session, JsonUtil.toJsonString(buildCurrentDayMessage(session, eventType)));
  54 + }
  55 +
  56 + private SupplierQuotationProjectRealtimeMessage buildCurrentDayMessage(WebSocketSession session, String eventType) {
  57 + LocalDate today = LocalDate.now();
  58 + String userId = getUserId(session);
  59 + List<SupplierQuotationProject> records = supplierQuotationProjectService.queryCurrentDayFinishedBoardList(today, userId);
  60 +
  61 + SupplierQuotationProjectRealtimeMessage message = new SupplierQuotationProjectRealtimeMessage();
  62 + message.setMessageType("FULL_SYNC_FINISHED");
  63 + message.setEventType(eventType);
  64 + message.setBusinessDate(today);
  65 + message.setPushTime(LocalDateTime.now());
  66 + message.setRecords(records);
  67 + return message;
  68 + }
  69 +
  70 + private void sendMessage(WebSocketSession session, String payload) {
  71 + if (session == null || !session.isOpen()) {
  72 + unregister(session);
  73 + return;
  74 + }
  75 +
  76 + try {
  77 + synchronized (session) {
  78 + session.sendMessage(new TextMessage(payload));
  79 + }
  80 + } catch (IOException e) {
  81 + log.warn("供应商报价项目结束态实时推送失败,sessionId={}", session.getId(), e);
  82 + unregister(session);
  83 + }
  84 + }
  85 +
  86 + private String getUserId(WebSocketSession session) {
  87 + Object userId = session.getAttributes().get(SupplierQuotationProjectWebSocketHandshakeInterceptor.ATTR_USER_ID);
  88 + return userId == null ? StringUtils.EMPTY : String.valueOf(userId);
  89 + }
  90 +}
  91 +
... ...
  1 +package com.lframework.xingyun.sc.procurement.websocket.quotation.project;
  2 +
  3 +import javax.annotation.Resource;
  4 +import org.springframework.context.annotation.Configuration;
  5 +import org.springframework.web.socket.config.annotation.EnableWebSocket;
  6 +import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
  7 +import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
  8 +
  9 +@Configuration
  10 +@EnableWebSocket
  11 +public class SupplierQuotationProjectFinishedWebSocketConfig implements WebSocketConfigurer {
  12 +
  13 + public static final String ENDPOINT = "/ws/procurement/supplierQuotationProject/finished/realtime";
  14 +
  15 + @Resource
  16 + private SupplierQuotationProjectFinishedWebSocketHandler webSocketHandler;
  17 + @Resource
  18 + private SupplierQuotationProjectWebSocketHandshakeInterceptor handshakeInterceptor;
  19 +
  20 + @Override
  21 + public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
  22 + registry.addHandler(webSocketHandler, ENDPOINT)
  23 + .addInterceptors(handshakeInterceptor)
  24 + .setAllowedOrigins("*");
  25 + }
  26 +}
  27 +
... ...
  1 +package com.lframework.xingyun.sc.procurement.websocket.quotation.project;
  2 +
  3 +import javax.annotation.Resource;
  4 +import lombok.extern.slf4j.Slf4j;
  5 +import org.apache.commons.lang3.StringUtils;
  6 +import org.springframework.stereotype.Component;
  7 +import org.springframework.web.socket.CloseStatus;
  8 +import org.springframework.web.socket.TextMessage;
  9 +import org.springframework.web.socket.WebSocketSession;
  10 +import org.springframework.web.socket.handler.TextWebSocketHandler;
  11 +
  12 +@Slf4j
  13 +@Component
  14 +public class SupplierQuotationProjectFinishedWebSocketHandler extends TextWebSocketHandler {
  15 +
  16 + @Resource
  17 + private SupplierQuotationProjectFinishedRealtimePushService realtimePushService;
  18 +
  19 + @Override
  20 + public void afterConnectionEstablished(WebSocketSession session) {
  21 + realtimePushService.register(session);
  22 + realtimePushService.replayCurrentDayFinishedData(session, "INIT");
  23 + }
  24 +
  25 + @Override
  26 + protected void handleTextMessage(WebSocketSession session, TextMessage message) {
  27 + String payload = StringUtils.trimToEmpty(message.getPayload());
  28 + if ("SYNC_TODAY".equalsIgnoreCase(payload) || "RESYNC".equalsIgnoreCase(payload)) {
  29 + realtimePushService.replayCurrentDayFinishedData(session, "RESYNC");
  30 + }
  31 + }
  32 +
  33 + @Override
  34 + public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
  35 + realtimePushService.unregister(session);
  36 + }
  37 +
  38 + @Override
  39 + public void handleTransportError(WebSocketSession session, Throwable exception) {
  40 + log.warn("供应商报价项目结束态 WebSocket 连接异常,sessionId={}", session.getId(), exception);
  41 + realtimePushService.unregister(session);
  42 + }
  43 +}
  44 +
... ...
... ... @@ -96,5 +96,12 @@
96 96 AND tb.status='PUBLISHED'
97 97 ORDER BY tb.create_time DESC, tb.id DESC
98 98 </select>
  99 +
  100 + <select id="queryCurrentDayFinishedList" resultMap="SupplierQuotationProject">
  101 + <include refid="SupplierQuotationProjectSql"/>
  102 + WHERE DATE(tb.create_time) = #{day}
  103 + AND tb.status IN ('COMPLETED', 'ABORTED')
  104 + ORDER BY tb.update_time DESC, tb.id DESC
  105 + </select>
99 106 </mapper>
100 107
... ...