zhuyifan

fix

1 package com.infoloop.tianting.controller; 1 package com.infoloop.tianting.controller;
2 2
3 import com.github.xiaoymin.knife4j.annotations.ApiSupport; 3 import com.github.xiaoymin.knife4j.annotations.ApiSupport;
4 +import com.infoloop.tianting.model.dto.MenuDbDTO;
4 import com.infoloop.tianting.model.dto.MenuDbDTO.BatchCreateMenuRefsDto; 5 import com.infoloop.tianting.model.dto.MenuDbDTO.BatchCreateMenuRefsDto;
5 import com.infoloop.tianting.model.dto.MenuDbDTO.BatchCreateMenuRefsResponseDto; 6 import com.infoloop.tianting.model.dto.MenuDbDTO.BatchCreateMenuRefsResponseDto;
6 import com.infoloop.tianting.model.dto.MenuDbDTO.MenuDetailDto; 7 import com.infoloop.tianting.model.dto.MenuDbDTO.MenuDetailDto;
...@@ -40,11 +41,11 @@ public class MenuController { ...@@ -40,11 +41,11 @@ public class MenuController {
40 return menuService.queryMiniProgramPublishedMenusByStallId(enterpriseId, stallId); 41 return menuService.queryMiniProgramPublishedMenusByStallId(enterpriseId, stallId);
41 } 42 }
42 43
43 - @ApiOperation(value = "根据stallId获取所有已发布餐单") 44 + @ApiOperation(value = "根据stallIds获取所有已发布餐单")
44 - @GetMapping("/enterprises/{enterpriseId}/stalls/{stallId}/all/menus") 45 + @PostMapping("/enterprises/{enterpriseId}/stalls/all/menus")
45 @ResponseStatus(HttpStatus.OK) 46 @ResponseStatus(HttpStatus.OK)
46 - public List<MenuDto> queryPublishedMenusByStallIds(@PathVariable Integer enterpriseId, @PathVariable Integer stallId) { 47 + public List<MenuDto> queryPublishedMenusByStallIds(@PathVariable Integer enterpriseId, @Valid @RequestBody final MenuDbDTO.QueryStallMenuDTO queryStallMenuDTO) {
47 - return menuService.queryPublishedMenusByStallId(enterpriseId, stallId); 48 + return menuService.queryPublishedMenusByStallId(enterpriseId, queryStallMenuDTO.getStallIds());
48 } 49 }
49 50
50 @ApiOperation(value = "根据MenuId获取餐单") 51 @ApiOperation(value = "根据MenuId获取餐单")
......
...@@ -5,16 +5,15 @@ import com.infoloop.tianting.menuservice.CloseTimeTypeEnum; ...@@ -5,16 +5,15 @@ import com.infoloop.tianting.menuservice.CloseTimeTypeEnum;
5 import com.infoloop.tianting.menuservice.DishSelectRuleEnum; 5 import com.infoloop.tianting.menuservice.DishSelectRuleEnum;
6 import com.infoloop.tianting.menuservice.DishTypeEnum; 6 import com.infoloop.tianting.menuservice.DishTypeEnum;
7 import com.infoloop.tianting.menuservice.ModeOfPaymentEnum; 7 import com.infoloop.tianting.menuservice.ModeOfPaymentEnum;
8 -import com.infoloop.tianting.model.dto.MenuDbDTO.CreateMenuRefsDto;
9 import io.swagger.annotations.ApiModel; 8 import io.swagger.annotations.ApiModel;
10 import io.swagger.annotations.ApiModelProperty; 9 import io.swagger.annotations.ApiModelProperty;
11 -import io.swagger.models.auth.In;
12 -import java.time.LocalDateTime;
13 -import java.util.List;
14 import lombok.Builder; 10 import lombok.Builder;
15 import lombok.Data; 11 import lombok.Data;
16 import lombok.ToString; 12 import lombok.ToString;
17 13
14 +import javax.validation.constraints.NotEmpty;
15 +import java.util.List;
16 +
18 @Data 17 @Data
19 @ApiModel(description = "餐单DTO") 18 @ApiModel(description = "餐单DTO")
20 public class MenuDbDTO { 19 public class MenuDbDTO {
...@@ -152,4 +151,14 @@ public class MenuDbDTO { ...@@ -152,4 +151,14 @@ public class MenuDbDTO {
152 private List<Integer> ids; 151 private List<Integer> ids;
153 } 152 }
154 153
154 + @Data
155 + @Builder
156 + @ToString
157 + @ApiModel(description = "查询档口餐单")
158 + public static class QueryStallMenuDTO {
159 +
160 + @NotEmpty(message = "stallIds不能为空")
161 + private List<Integer> stallIds;
162 + }
163 +
155 } 164 }
......
...@@ -271,7 +271,7 @@ public class OrderDbDTO { ...@@ -271,7 +271,7 @@ public class OrderDbDTO {
271 private Integer customerId; 271 private Integer customerId;
272 272
273 @ApiModelProperty(value = "状态订单;待备餐=1,备餐中=2,部分出餐=3,已出餐=4,已取消=5") 273 @ApiModelProperty(value = "状态订单;待备餐=1,备餐中=2,部分出餐=3,已出餐=4,已取消=5")
274 - private Integer status; 274 + private OrderStatusEnum status;
275 275
276 @ApiModelProperty(value = "餐单 id") 276 @ApiModelProperty(value = "餐单 id")
277 @NotNull(message = "餐单 id不能为空") 277 @NotNull(message = "餐单 id不能为空")
......
1 +package com.infoloop.tianting.server;
2 +
3 +import com.infoloop.tianting.server.session.UserTypeEnum;
4 +import lombok.Builder;
5 +import lombok.Data;
6 +
7 +@Data
8 +@Builder
9 +public class UserAuthData {
10 + private int operatorId;
11 + private UserTypeEnum userType;
12 +}
...@@ -7,14 +7,17 @@ import com.infoloop.tianting.server.session.UserSessionData; ...@@ -7,14 +7,17 @@ import com.infoloop.tianting.server.session.UserSessionData;
7 import com.infoloop.tianting.server.session.UserSessionKey; 7 import com.infoloop.tianting.server.session.UserSessionKey;
8 import com.infoloop.tianting.server.session.UserTypeEnum; 8 import com.infoloop.tianting.server.session.UserTypeEnum;
9 import lombok.extern.slf4j.Slf4j; 9 import lombok.extern.slf4j.Slf4j;
10 +import org.apache.commons.lang3.StringUtils;
10 import org.springframework.web.socket.CloseStatus; 11 import org.springframework.web.socket.CloseStatus;
11 import org.springframework.web.socket.TextMessage; 12 import org.springframework.web.socket.TextMessage;
12 import org.springframework.web.socket.WebSocketSession; 13 import org.springframework.web.socket.WebSocketSession;
13 import org.springframework.web.socket.handler.TextWebSocketHandler; 14 import org.springframework.web.socket.handler.TextWebSocketHandler;
14 15
16 +import javax.annotation.Nullable;
15 import java.io.IOException; 17 import java.io.IOException;
16 import java.util.List; 18 import java.util.List;
17 import java.util.concurrent.ConcurrentHashMap; 19 import java.util.concurrent.ConcurrentHashMap;
20 +import java.util.concurrent.CopyOnWriteArrayList;
18 import java.util.concurrent.Executors; 21 import java.util.concurrent.Executors;
19 import java.util.concurrent.ScheduledExecutorService; 22 import java.util.concurrent.ScheduledExecutorService;
20 import java.util.concurrent.TimeUnit; 23 import java.util.concurrent.TimeUnit;
...@@ -23,7 +26,7 @@ import java.util.stream.Collectors; ...@@ -23,7 +26,7 @@ import java.util.stream.Collectors;
23 @Slf4j 26 @Slf4j
24 public class WebSocketServer extends TextWebSocketHandler { 27 public class WebSocketServer extends TextWebSocketHandler {
25 28
26 - private static final ConcurrentHashMap<UserSessionKey, UserSessionData> userSessions = new ConcurrentHashMap<>(); 29 + private static final ConcurrentHashMap<UserSessionKey, List<UserSessionData>> userSessions = new ConcurrentHashMap<>();
27 private static final long INACTIVITY_TIMEOUT = 60 * 60 * 1000; 30 private static final long INACTIVITY_TIMEOUT = 60 * 60 * 1000;
28 private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); 31 private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
29 32
...@@ -33,38 +36,47 @@ public class WebSocketServer extends TextWebSocketHandler { ...@@ -33,38 +36,47 @@ public class WebSocketServer extends TextWebSocketHandler {
33 36
34 private static void cleanInactiveSessions() { 37 private static void cleanInactiveSessions() {
35 final var currentTime = System.currentTimeMillis(); 38 final var currentTime = System.currentTimeMillis();
36 - final var iterator = userSessions.entrySet().iterator(); 39 + userSessions.forEach((key, sessionList) ->
37 - log.info("cleanInactiveSessions; sessions:{}", userSessions.keySet()); 40 + userSessions.computeIfPresent(key, (k, sessions) -> {
38 - while (iterator.hasNext()) { 41 + sessions.removeIf(userData -> {
39 - final var entry = iterator.next(); 42 + if (currentTime - userData.getLastActiveTime() > INACTIVITY_TIMEOUT) {
40 - final var key = entry.getKey();
41 - final var userData = entry.getValue();
42 - final var lastActiveTime = userData.getLastActiveTime();
43 - if (currentTime - lastActiveTime > INACTIVITY_TIMEOUT) {
44 try { 43 try {
45 userData.closeSession(); 44 userData.closeSession();
46 - log.info("closeSession,userId : {}, userType : {}", key.getUserId(), key.getUserType()); 45 + log.info("closeSession, userId: {}, userType: {}", key.getUserId(), key.getUserType());
47 } catch (IOException e) { 46 } catch (IOException e) {
48 - log.error("closeSession error,userId : {}, userType : {}", key.getUserId(), key.getUserType(), e); 47 + log.error("closeSession error, userId: {}, userType: {}", key.getUserId(), key.getUserType(), e);
49 - }
50 - iterator.remove();
51 } 48 }
49 + return true;
52 } 50 }
51 + return false;
52 + });
53 + return sessions.isEmpty() ? null : sessions; // 为空时移除
54 + })
55 + );
53 } 56 }
54 57
58 +
55 public static <T> void sendMessageToUser(UserSessionKey key, SocketMessage<T> socketMessage) throws IOException { 59 public static <T> void sendMessageToUser(UserSessionKey key, SocketMessage<T> socketMessage) throws IOException {
56 sendMessageToUsers(List.of(key), socketMessage); 60 sendMessageToUsers(List.of(key), socketMessage);
57 } 61 }
58 62
59 public static <T> void sendMessageToUsers(List<UserSessionKey> keys, SocketMessage<T> socketMessage) throws IOException { 63 public static <T> void sendMessageToUsers(List<UserSessionKey> keys, SocketMessage<T> socketMessage) throws IOException {
60 for (final var key : keys) { 64 for (final var key : keys) {
61 - final var userData = userSessions.get(key); 65 + final var sessionList = userSessions.get(key);
62 - if (userData != null && userData.getSession().isOpen()) { 66 + if (sessionList != null) {
67 + sessionList.forEach(userData -> {
68 + try {
69 + if (userData.getSession().isOpen()) {
63 userData.getSession().sendMessage(new TextMessage(socketMessage.toJsonString())); 70 userData.getSession().sendMessage(new TextMessage(socketMessage.toJsonString()));
64 userData.updateLastActiveTime(); 71 userData.updateLastActiveTime();
65 - log.info("send message to userId : {}, userType : {}", key.getUserId(), key.getUserType()); 72 + log.info("Send message to userId: {}, userType: {}", key.getUserId(), key.getUserType());
66 } else { 73 } else {
67 - log.info("userId : {}, userType : {} WebSocket connect closed; ", key.getUserId(), key.getUserType()); 74 + log.info("WebSocket closed; userId: {}, userType: {}", key.getUserId(), key.getUserType());
75 + }
76 + } catch (IOException e) {
77 + log.error("Failed to send message; userId: {}, userType: {}", key.getUserId(), key.getUserType(), e);
78 + }
79 + });
68 } 80 }
69 } 81 }
70 } 82 }
...@@ -75,39 +87,40 @@ public class WebSocketServer extends TextWebSocketHandler { ...@@ -75,39 +87,40 @@ public class WebSocketServer extends TextWebSocketHandler {
75 87
76 public static <T> void sendMessageByUserTypes(List<UserTypeEnum> userTypes, SocketMessage<T> socketMessage) throws IOException { 88 public static <T> void sendMessageByUserTypes(List<UserTypeEnum> userTypes, SocketMessage<T> socketMessage) throws IOException {
77 final var keys = userSessions.keySet().stream() 89 final var keys = userSessions.keySet().stream()
78 - .filter(userSessionData -> userTypes.contains(userSessionData.getUserType())) 90 + .filter(userKey -> userTypes.contains(userKey.getUserType()))
79 .collect(Collectors.toList()); 91 .collect(Collectors.toList());
80 sendMessageToUsers(keys, socketMessage); 92 sendMessageToUsers(keys, socketMessage);
81 } 93 }
82 94
83 - public static <T> void sendMessageByUserTypes(List<UserTypeEnum> userTypes, List<String> authUserIds, SocketMessage<T> socketMessage) throws IOException { 95 + public static <T> void sendMessageByUserTypes(List<UserTypeEnum> userTypes, List<UserAuthData> userAuthData, SocketMessage<T> socketMessage) throws IOException {
84 final var keys = userSessions.keySet().stream() 96 final var keys = userSessions.keySet().stream()
85 - .filter(userSessionData -> userTypes.contains(userSessionData.getUserType())) 97 + .filter(userKey -> userTypes.contains(userKey.getUserType()))
86 - .filter(userSessionData -> authUserIds.contains(userSessionData.getUserId())) 98 + .filter(userKey -> userAuthData.isEmpty()
99 + || userAuthData.stream().anyMatch(data -> String.valueOf(data.getOperatorId()).equals(userKey.getUserId()) && data.getUserType().equals(userKey.getUserType())))
87 .collect(Collectors.toList()); 100 .collect(Collectors.toList());
88 sendMessageToUsers(keys, socketMessage); 101 sendMessageToUsers(keys, socketMessage);
89 } 102 }
90 103
91 public static void closeConnection(UserSessionKey key) { 104 public static void closeConnection(UserSessionKey key) {
92 - final var userData = userSessions.get(key); 105 + userSessions.computeIfPresent(key, (k, sessionList) -> {
93 - if (userData != null) { 106 + sessionList.forEach(userData -> {
94 try { 107 try {
95 userData.closeSession(); 108 userData.closeSession();
96 - userSessions.remove(key);
97 - log.info("WebSocket close; userId = {}, userType = {}", key.getUserId(), key.getUserType());
98 } catch (IOException e) { 109 } catch (IOException e) {
99 - log.error("WebSocket close failed: userId = {}, userType = {}", key.getUserId(), key.getUserType(), e); 110 + log.error("WebSocket close failed: userId: {}, userType: {}", key.getUserId(), key.getUserType(), e);
100 - }
101 - } else {
102 - log.warn("Not Found userId : {}, userType : {} WebSocket Connect ", key.getUserId(), key.getUserType());
103 } 111 }
112 + });
113 + return null; // 直接返回 null,移除 key
114 + });
115 + log.info("WebSocket closed; userId: {}, userType: {}", key.getUserId(), key.getUserType());
104 } 116 }
105 117
118 + @Nullable
106 private UserSessionKey getUserSessionKey(WebSocketSession session) { 119 private UserSessionKey getUserSessionKey(WebSocketSession session) {
107 final var userId = (String) session.getAttributes().get(CommonConstants.USER_ID); 120 final var userId = (String) session.getAttributes().get(CommonConstants.USER_ID);
108 final var userTypeStr = (String) session.getAttributes().get(CommonConstants.USER_TYPE); 121 final var userTypeStr = (String) session.getAttributes().get(CommonConstants.USER_TYPE);
109 final var userType = UserTypeEnum.fromString(userTypeStr); 122 final var userType = UserTypeEnum.fromString(userTypeStr);
110 - if (userId != null && userType != null) { 123 + if (StringUtils.isNotEmpty(userId) && userType != null) {
111 return UserSessionKey.builder().userId(userId).userType(userType).build(); 124 return UserSessionKey.builder().userId(userId).userType(userType).build();
112 } 125 }
113 return null; 126 return null;
...@@ -117,30 +130,25 @@ public class WebSocketServer extends TextWebSocketHandler { ...@@ -117,30 +130,25 @@ public class WebSocketServer extends TextWebSocketHandler {
117 public void afterConnectionEstablished(WebSocketSession session) { 130 public void afterConnectionEstablished(WebSocketSession session) {
118 final var key = getUserSessionKey(session); 131 final var key = getUserSessionKey(session);
119 if (key != null) { 132 if (key != null) {
120 - final var existingSession = userSessions.remove(key); 133 + userSessions.computeIfAbsent(key, k -> new CopyOnWriteArrayList<>()).add(new UserSessionData(session));
121 - if (existingSession != null) { 134 + log.info("WebSocket connection established; userId: {}, userType: {}", key.getUserId(), key.getUserType());
122 - try {
123 - existingSession.closeSession();
124 - log.info("WebSocket old connect closed,userId : {}, userType : {}", key.getUserId(), key.getUserType());
125 - } catch (IOException e) {
126 - log.error("old WebSocket close failed,userId : {}, userType : {}", key.getUserId(), key.getUserType(), e);
127 - }
128 - }
129 - userSessions.put(key, new UserSessionData(session));
130 - log.info("WebSocket connect success, userId : {}, userType : {}", key.getUserId(), key.getUserType());
131 } else { 135 } else {
132 - log.warn("WebSocket connect failed,unable to get valid user information"); 136 + log.warn("WebSocket connection failed; unable to retrieve valid user information");
133 } 137 }
134 } 138 }
135 139
140 +
136 @Override 141 @Override
137 public void afterConnectionClosed(WebSocketSession session, CloseStatus status) { 142 public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
138 final var key = getUserSessionKey(session); 143 final var key = getUserSessionKey(session);
139 if (key != null) { 144 if (key != null) {
140 - userSessions.remove(key); 145 + userSessions.computeIfPresent(key, (k, sessionList) -> {
141 - log.info("WebSocket closed: userId : {}, userType : {}", key.getUserId(), key.getUserType()); 146 + sessionList.removeIf(userData -> userData.getSession().getId().equals(session.getId()));
147 + return sessionList.isEmpty() ? null : sessionList;
148 + });
149 + log.info("WebSocket closed; userId: {}, userType: {}", key.getUserId(), key.getUserType());
142 } else { 150 } else {
143 - log.warn("WebSocket closed failed,unable to get valid user information"); 151 + log.warn("WebSocket closed; unable to retrieve valid user information");
144 } 152 }
145 } 153 }
146 } 154 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -13,7 +13,7 @@ public interface MenuService { ...@@ -13,7 +13,7 @@ public interface MenuService {
13 13
14 List<MenuDto> queryMiniProgramPublishedMenusByStallId(Integer enterpriseId, Integer stallId); 14 List<MenuDto> queryMiniProgramPublishedMenusByStallId(Integer enterpriseId, Integer stallId);
15 15
16 - List<MenuDto> queryPublishedMenusByStallId(Integer enterpriseId, Integer stallId); 16 + List<MenuDto> queryPublishedMenusByStallId(Integer enterpriseId, List<Integer> stallIds);
17 17
18 MenuDto getMenuById(Integer enterpriseId, Integer id); 18 MenuDto getMenuById(Integer enterpriseId, Integer id);
19 19
......
1 package com.infoloop.tianting.service.client; 1 package com.infoloop.tianting.service.client;
2 2
3 import com.infoloop.tianting.enterpriseresourcetagservice.EnterpriseResourceTagServiceRpcGrpc; 3 import com.infoloop.tianting.enterpriseresourcetagservice.EnterpriseResourceTagServiceRpcGrpc;
4 +import com.infoloop.tianting.enterpriseresourcetagservice.GetOperatorIdsByStallIdRpcRequest;
4 import com.infoloop.tianting.enterpriseresourcetagservice.UserTagsAndResourcesGetRequest; 5 import com.infoloop.tianting.enterpriseresourcetagservice.UserTagsAndResourcesGetRequest;
5 import com.infoloop.tianting.enterpriseresourcetagservice.UserTagsAndResourcesGetResponse; 6 import com.infoloop.tianting.enterpriseresourcetagservice.UserTagsAndResourcesGetResponse;
6 import lombok.RequiredArgsConstructor; 7 import lombok.RequiredArgsConstructor;
7 import org.springframework.beans.factory.annotation.Autowired; 8 import org.springframework.beans.factory.annotation.Autowired;
8 import org.springframework.stereotype.Service; 9 import org.springframework.stereotype.Service;
9 10
11 +import java.util.List;
12 +
10 @Service 13 @Service
11 @RequiredArgsConstructor(onConstructor = @__(@Autowired)) 14 @RequiredArgsConstructor(onConstructor = @__(@Autowired))
12 public class EnterpriseResourceServiceRpcClient { 15 public class EnterpriseResourceServiceRpcClient {
...@@ -21,4 +24,12 @@ public class EnterpriseResourceServiceRpcClient { ...@@ -21,4 +24,12 @@ public class EnterpriseResourceServiceRpcClient {
21 .build(); 24 .build();
22 return enterpriseResourceTagServiceRpcBlockingStub.getUserResources(request); 25 return enterpriseResourceTagServiceRpcBlockingStub.getUserResources(request);
23 } 26 }
27 +
28 + public List<Integer> getOperatorIdsByStallId(int enterpriseId, int stallId) {
29 + final var request = GetOperatorIdsByStallIdRpcRequest.newBuilder()
30 + .setEnterpriseId(enterpriseId)
31 + .setStallId(stallId)
32 + .build();
33 + return enterpriseResourceTagServiceRpcBlockingStub.getOperatorIdsByStallId(request).getOperatorIdsList();
34 + }
24 } 35 }
......
...@@ -45,11 +45,10 @@ public class MenuServiceRpcClient { ...@@ -45,11 +45,10 @@ public class MenuServiceRpcClient {
45 return menuServiceRpcBlockingStub.getMicroPublishedMenusByStallIds(request); 45 return menuServiceRpcBlockingStub.getMicroPublishedMenusByStallIds(request);
46 } 46 }
47 47
48 - public GetPublishedMenusByStallIdsRpcResponse queryPublishedMenusByStallId( 48 + public GetPublishedMenusByStallIdsRpcResponse queryPublishedMenusByStallId(Integer enterpriseId, List<Integer> stallIds) {
49 - Integer enterpriseId, Integer stallId) {
50 final var request = GetPublishedMenusByStallIdsRpcRequest.newBuilder() 49 final var request = GetPublishedMenusByStallIdsRpcRequest.newBuilder()
51 .setEnterpriseId(enterpriseId) 50 .setEnterpriseId(enterpriseId)
52 - .addAllStallIds(List.of(stallId)) 51 + .addAllStallIds(stallIds)
53 .build(); 52 .build();
54 return menuServiceRpcBlockingStub.getPublishedMenusByStallIds(request); 53 return menuServiceRpcBlockingStub.getPublishedMenusByStallIds(request);
55 } 54 }
......
...@@ -67,6 +67,7 @@ import com.infoloop.tianting.model.dto.OrderDbDTO.OrderDetailOperationDto; ...@@ -67,6 +67,7 @@ import com.infoloop.tianting.model.dto.OrderDbDTO.OrderDetailOperationDto;
67 import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByConditionDto; 67 import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByConditionDto;
68 import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByPaginationDto; 68 import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByPaginationDto;
69 import com.infoloop.tianting.model.dto.OrderDbDTO.UpdateOrderDto; 69 import com.infoloop.tianting.model.dto.OrderDbDTO.UpdateOrderDto;
70 +import com.infoloop.tianting.server.UserAuthData;
70 import com.infoloop.tianting.server.WebSocketServer; 71 import com.infoloop.tianting.server.WebSocketServer;
71 import com.infoloop.tianting.server.message.MessageTypeEnum; 72 import com.infoloop.tianting.server.message.MessageTypeEnum;
72 import com.infoloop.tianting.server.message.NoticeTypeEnum; 73 import com.infoloop.tianting.server.message.NoticeTypeEnum;
...@@ -105,6 +106,7 @@ public class OrderServiceRpcClient { ...@@ -105,6 +106,7 @@ public class OrderServiceRpcClient {
105 private final SkuServiceRpcClient skuServiceRpcClient; 106 private final SkuServiceRpcClient skuServiceRpcClient;
106 private final OperatorServiceRpcClient operatorServiceRpcClient; 107 private final OperatorServiceRpcClient operatorServiceRpcClient;
107 private final ClientResourceTagServiceRpcClient clientResourceTagServiceRpcClient; 108 private final ClientResourceTagServiceRpcClient clientResourceTagServiceRpcClient;
109 + private final EnterpriseResourceServiceRpcClient enterpriseResourceServiceRpcClient;
108 private final RedissonClient redissonClient; 110 private final RedissonClient redissonClient;
109 private final DelayedQueue<AutoCancelParam> delayedQueue; 111 private final DelayedQueue<AutoCancelParam> delayedQueue;
110 112
...@@ -547,7 +549,7 @@ public class OrderServiceRpcClient { ...@@ -547,7 +549,7 @@ public class OrderServiceRpcClient {
547 OrderStatusEnum orderStatus = OrderStatusEnum.TO_PREPARE; 549 OrderStatusEnum orderStatus = OrderStatusEnum.TO_PREPARE;
548 if (createOrderDto.getOnlinePay() != OnlinePayEnum.ONLINE) { 550 if (createOrderDto.getOnlinePay() != OnlinePayEnum.ONLINE) {
549 var orderRuleJson = menuById.getResponse().getOrderRuleJson(); 551 var orderRuleJson = menuById.getResponse().getOrderRuleJson();
550 - if (orderRuleJson.getModeOfPayment() == ModeOfPaymentEnum.ONLINE && orderRuleJson.getCloseTimeType() == CloseTimeTypeEnum.IMMEDIATELY) { 552 + if (orderRuleJson.getModeOfPayment() != ModeOfPaymentEnum.ONLINE && orderRuleJson.getCloseTimeType() == CloseTimeTypeEnum.IMMEDIATELY) {
551 orderStatus = OrderStatusEnum.PREPARING; 553 orderStatus = OrderStatusEnum.PREPARING;
552 } 554 }
553 } 555 }
...@@ -555,7 +557,7 @@ public class OrderServiceRpcClient { ...@@ -555,7 +557,7 @@ public class OrderServiceRpcClient {
555 .setShouldCreateCustomerId(createOrderDto.getShouldCreateCustomerId()) 557 .setShouldCreateCustomerId(createOrderDto.getShouldCreateCustomerId())
556 .setShouldCreateCustomerId(true).setCustomerId(createOrderDto.getCustomerId()) 558 .setShouldCreateCustomerId(true).setCustomerId(createOrderDto.getCustomerId())
557 .setStallId(createOrderDto.getStallId()) 559 .setStallId(createOrderDto.getStallId())
558 - .setStatus(orderStatus) 560 + .setStatus(createOrderDto.getStatus() != null ? createOrderDto.getStatus() : orderStatus)
559 .setAddress(createOrderDto.getAddress()) 561 .setAddress(createOrderDto.getAddress())
560 .setClientId(createOrderDto.getClientId()) 562 .setClientId(createOrderDto.getClientId())
561 .setShouldCreateOpenId(!LoginContextHolder.getOpenId().isEmpty()).setOpenId(LoginContextHolder.getOpenId()) 563 .setShouldCreateOpenId(!LoginContextHolder.getOpenId().isEmpty()).setOpenId(LoginContextHolder.getOpenId())
...@@ -605,7 +607,6 @@ public class OrderServiceRpcClient { ...@@ -605,7 +607,6 @@ public class OrderServiceRpcClient {
605 if (orderResponse.getIsCreated()) { 607 if (orderResponse.getIsCreated()) {
606 // 用餐时间为当天,并且非在线支付餐单,发送消息给客户端 608 // 用餐时间为当天,并且非在线支付餐单,发送消息给客户端
607 if (createOrderDto.getMealTime().toLocalDate().equals(LocalDate.now()) && menuById.getResponse().getOrderRuleJson().getModeOfPayment() != ModeOfPaymentEnum.ONLINE) { 609 if (createOrderDto.getMealTime().toLocalDate().equals(LocalDate.now()) && menuById.getResponse().getOrderRuleJson().getModeOfPayment() != ModeOfPaymentEnum.ONLINE) {
608 - final var userIds = clientResourceTagServiceRpcClient.getOperatorIdsByStallIds(List.of(createOrderDto.getStallId())).stream().map(SingleResourceLabelEntityRefsResponse::getEntityId).distinct().map(String::valueOf).collect(Collectors.toList());
609 final var orderCreateSuccessData = OrderCreateSuccessData.builder() 610 final var orderCreateSuccessData = OrderCreateSuccessData.builder()
610 .orderId(orderResponse.getId()) 611 .orderId(orderResponse.getId())
611 .build(); 612 .build();
...@@ -616,8 +617,14 @@ public class OrderServiceRpcClient { ...@@ -616,8 +617,14 @@ public class OrderServiceRpcClient {
616 .message("有新的订单下单成功啦,快去查看吧~") 617 .message("有新的订单下单成功啦,快去查看吧~")
617 .data(orderCreateSuccessData) 618 .data(orderCreateSuccessData)
618 .build(); 619 .build();
620 + final var clientOperatorIds = clientResourceTagServiceRpcClient.getOperatorIdsByStallIds(List.of(createOrderDto.getStallId())).stream().map(SingleResourceLabelEntityRefsResponse::getEntityId).distinct().collect(Collectors.toList());
621 + final var enterpriseOperatorIds = enterpriseResourceServiceRpcClient.getOperatorIdsByStallId(createOrderDto.getEnterpriseId(), createOrderDto.getStallId());
622 + final var userAuthData = new ArrayList<UserAuthData>();
623 + userAuthData.addAll(clientOperatorIds.stream().map(e -> UserAuthData.builder().operatorId(e).userType(UserTypeEnum.CLIENT).build()).collect(Collectors.toList()));
624 + userAuthData.addAll(enterpriseOperatorIds.stream().map(e -> UserAuthData.builder().operatorId(e).userType(UserTypeEnum.KDS).build()).collect(Collectors.toList()));
625 + log.info("received userAuthData:{}", userAuthData);
619 try { 626 try {
620 - WebSocketServer.sendMessageByUserTypes(List.of(UserTypeEnum.CLIENT, UserTypeEnum.KDS), userIds, data); 627 + WebSocketServer.sendMessageByUserTypes(List.of(UserTypeEnum.CLIENT, UserTypeEnum.KDS), userAuthData, data);
621 } catch (IOException e) { 628 } catch (IOException e) {
622 log.error("Failed to send message to user", e); 629 log.error("Failed to send message to user", e);
623 } 630 }
......
...@@ -10,6 +10,7 @@ import com.fasterxml.jackson.dataformat.xml.XmlMapper; ...@@ -10,6 +10,7 @@ import com.fasterxml.jackson.dataformat.xml.XmlMapper;
10 import com.infoloop.tianting.clientcustomerorderservice.ClientCustomerOrderModification; 10 import com.infoloop.tianting.clientcustomerorderservice.ClientCustomerOrderModification;
11 import com.infoloop.tianting.clientcustomerorderservice.OrderStatusEnum; 11 import com.infoloop.tianting.clientcustomerorderservice.OrderStatusEnum;
12 import com.infoloop.tianting.clientcustomerorderservice.PayStatusEnum; 12 import com.infoloop.tianting.clientcustomerorderservice.PayStatusEnum;
13 +import com.infoloop.tianting.clientresourcetagservice.SingleResourceLabelEntityRefsResponse;
13 import com.infoloop.tianting.config.BusinessConfig; 14 import com.infoloop.tianting.config.BusinessConfig;
14 import com.infoloop.tianting.context.LoginContextHolder; 15 import com.infoloop.tianting.context.LoginContextHolder;
15 import com.infoloop.tianting.exception.ClientEndExceptions; 16 import com.infoloop.tianting.exception.ClientEndExceptions;
...@@ -19,10 +20,12 @@ import com.infoloop.tianting.model.dto.PayDTO.PayResponseDto; ...@@ -19,10 +20,12 @@ import com.infoloop.tianting.model.dto.PayDTO.PayResponseDto;
19 import com.infoloop.tianting.model.dto.PayDTO.ThirdPartyPayInformRequestDto; 20 import com.infoloop.tianting.model.dto.PayDTO.ThirdPartyPayInformRequestDto;
20 import com.infoloop.tianting.model.dto.PaymentCallbackDTO; 21 import com.infoloop.tianting.model.dto.PaymentCallbackDTO;
21 import com.infoloop.tianting.model.dto.PaymentCallbackResult; 22 import com.infoloop.tianting.model.dto.PaymentCallbackResult;
23 +import com.infoloop.tianting.server.UserAuthData;
22 import com.infoloop.tianting.server.WebSocketServer; 24 import com.infoloop.tianting.server.WebSocketServer;
23 import com.infoloop.tianting.server.message.MessageTypeEnum; 25 import com.infoloop.tianting.server.message.MessageTypeEnum;
24 import com.infoloop.tianting.server.message.NoticeTypeEnum; 26 import com.infoloop.tianting.server.message.NoticeTypeEnum;
25 import com.infoloop.tianting.server.message.SocketMessage; 27 import com.infoloop.tianting.server.message.SocketMessage;
28 +import com.infoloop.tianting.server.message.data.OrderCreateSuccessData;
26 import com.infoloop.tianting.server.message.data.OrderPaymentSuccessData; 29 import com.infoloop.tianting.server.message.data.OrderPaymentSuccessData;
27 import com.infoloop.tianting.server.session.UserSessionKey; 30 import com.infoloop.tianting.server.session.UserSessionKey;
28 import com.infoloop.tianting.server.session.UserTypeEnum; 31 import com.infoloop.tianting.server.session.UserTypeEnum;
...@@ -39,10 +42,15 @@ import org.springframework.http.ResponseEntity; ...@@ -39,10 +42,15 @@ import org.springframework.http.ResponseEntity;
39 import org.springframework.stereotype.Service; 42 import org.springframework.stereotype.Service;
40 import org.springframework.web.client.RestTemplate; 43 import org.springframework.web.client.RestTemplate;
41 44
45 +import java.io.IOException;
42 import java.math.BigDecimal; 46 import java.math.BigDecimal;
43 import java.text.MessageFormat; 47 import java.text.MessageFormat;
44 import java.text.ParseException; 48 import java.text.ParseException;
49 +import java.time.LocalDate;
45 import java.time.LocalDateTime; 50 import java.time.LocalDateTime;
51 +import java.util.ArrayList;
52 +import java.util.List;
53 +import java.util.stream.Collectors;
46 54
47 55
48 @Slf4j 56 @Slf4j
...@@ -56,6 +64,10 @@ public class PayServiceClient { ...@@ -56,6 +64,10 @@ public class PayServiceClient {
56 64
57 private final OrderServiceRpcClient orderServiceRpcClient; 65 private final OrderServiceRpcClient orderServiceRpcClient;
58 66
67 + private final ClientResourceTagServiceRpcClient clientResourceTagServiceRpcClient;
68 +
69 + private final EnterpriseResourceServiceRpcClient enterpriseResourceServiceRpcClient;
70 +
59 private final XmlMapper xmlMapper = new XmlMapper(); 71 private final XmlMapper xmlMapper = new XmlMapper();
60 72
61 public PayResponseDto payInform(PayInformRequestDto payRequestDto) { 73 public PayResponseDto payInform(PayInformRequestDto payRequestDto) {
...@@ -180,6 +192,29 @@ public class PayServiceClient { ...@@ -180,6 +192,29 @@ public class PayServiceClient {
180 .userId(orderById.getOpenId()) 192 .userId(orderById.getOpenId())
181 .userType(UserTypeEnum.MICRO) 193 .userType(UserTypeEnum.MICRO)
182 .build(), data); 194 .build(), data);
195 + if (LocalDate.now().equals(DateUtil.toLocalDate(orderById.getMealTime()))) {
196 + final var orderCreateSuccessData = OrderCreateSuccessData.builder()
197 + .orderId(orderById.getId())
198 + .build();
199 + final var createOrderData = SocketMessage.<OrderCreateSuccessData>builder()
200 + .type(MessageTypeEnum.ORDER)
201 + .noticeType(NoticeTypeEnum.ORDER_CREATED)
202 + .subject(NoticeTypeEnum.ORDER_CREATED.getDescription())
203 + .message("有新的订单下单成功啦,快去查看吧~")
204 + .data(orderCreateSuccessData)
205 + .build();
206 + final var clientOperatorIds = clientResourceTagServiceRpcClient.getOperatorIdsByStallIds(List.of(orderById.getStallId())).stream().map(SingleResourceLabelEntityRefsResponse::getEntityId).distinct().collect(Collectors.toList());
207 + final var enterpriseOperatorIds = enterpriseResourceServiceRpcClient.getOperatorIdsByStallId(orderById.getEnterpriseId(), orderById.getStallId());
208 + final var userAuthData = new ArrayList<UserAuthData>();
209 + userAuthData.addAll(clientOperatorIds.stream().map(e -> UserAuthData.builder().operatorId(e).userType(UserTypeEnum.CLIENT).build()).collect(Collectors.toList()));
210 + userAuthData.addAll(enterpriseOperatorIds.stream().map(e -> UserAuthData.builder().operatorId(e).userType(UserTypeEnum.KDS).build()).collect(Collectors.toList()));
211 + log.info("received userAuthData:{}", userAuthData);
212 + try {
213 + WebSocketServer.sendMessageByUserTypes(List.of(UserTypeEnum.CLIENT, UserTypeEnum.KDS), userAuthData, createOrderData);
214 + } catch (IOException e) {
215 + log.error("Failed to send message to user", e);
216 + }
217 + }
183 } 218 }
184 return updateResponse.getIsUpdated(); 219 return updateResponse.getIsUpdated();
185 } catch (JsonProcessingException e) { 220 } catch (JsonProcessingException e) {
......
...@@ -68,8 +68,8 @@ public class MenuServiceImpl implements MenuService { ...@@ -68,8 +68,8 @@ public class MenuServiceImpl implements MenuService {
68 } 68 }
69 69
70 @Override 70 @Override
71 - public List<MenuDto> queryPublishedMenusByStallId(Integer enterpriseId, Integer stallId) { 71 + public List<MenuDto> queryPublishedMenusByStallId(Integer enterpriseId, List<Integer> stallIds) {
72 - final var response = menuServiceRpcClient.queryPublishedMenusByStallId(enterpriseId, stallId); 72 + final var response = menuServiceRpcClient.queryPublishedMenusByStallId(enterpriseId, stallIds);
73 return response.getResponsesList().stream().map(menu -> 73 return response.getResponsesList().stream().map(menu ->
74 MenuDto.builder() 74 MenuDto.builder()
75 .id(menu.getId()) 75 .id(menu.getId())
...@@ -199,7 +199,7 @@ public class MenuServiceImpl implements MenuService { ...@@ -199,7 +199,7 @@ public class MenuServiceImpl implements MenuService {
199 199
200 @Override 200 @Override
201 public List<Integer> queryMenuSkuIdsByStallId(int enterpriseId, int stallId) { 201 public List<Integer> queryMenuSkuIdsByStallId(int enterpriseId, int stallId) {
202 - final var menuIds = menuServiceRpcClient.queryPublishedMenusByStallId(LoginContextHolder.getEnterpriseId(), stallId).getResponsesList().stream().map(SingleMenuRpcResponse::getId).collect(Collectors.toList()); 202 + final var menuIds = menuServiceRpcClient.queryPublishedMenusByStallId(LoginContextHolder.getEnterpriseId(), List.of(stallId)).getResponsesList().stream().map(SingleMenuRpcResponse::getId).collect(Collectors.toList());
203 return menuServiceRpcClient.queryMenuDetailsByMenuIds(LoginContextHolder.getEnterpriseId(), menuIds).getResponsesList().stream().map(SingleMenuDetailRpcResponse::getSkuId).distinct().collect(Collectors.toList()); 203 return menuServiceRpcClient.queryMenuDetailsByMenuIds(LoginContextHolder.getEnterpriseId(), menuIds).getResponsesList().stream().map(SingleMenuDetailRpcResponse::getSkuId).distinct().collect(Collectors.toList());
204 } 204 }
205 205
......
...@@ -113,6 +113,7 @@ public class OrderServiceImpl implements OrderService { ...@@ -113,6 +113,7 @@ public class OrderServiceImpl implements OrderService {
113 createOrderDto.setCreationSource(OrderSourceEnum.STALL.getNumber()); 113 createOrderDto.setCreationSource(OrderSourceEnum.STALL.getNumber());
114 createOrderDto.setEnterpriseId(operatorLoginInfo.getEnterpriseId()); 114 createOrderDto.setEnterpriseId(operatorLoginInfo.getEnterpriseId());
115 createOrderDto.setOnlinePay(operatorCreateOrderDto.getOnlinePay()); 115 createOrderDto.setOnlinePay(operatorCreateOrderDto.getOnlinePay());
116 + createOrderDto.setStatus(OrderStatusEnum.PREPARING);
116 OrderTypeEnum orderType; 117 OrderTypeEnum orderType;
117 if (menu.getOrderRuleJson().getCloseTimeType() == CloseTimeTypeEnum.RESERVATION) { 118 if (menu.getOrderRuleJson().getCloseTimeType() == CloseTimeTypeEnum.RESERVATION) {
118 orderType = OrderTypeEnum.DELIVERY; 119 orderType = OrderTypeEnum.DELIVERY;
......
...@@ -154,4 +154,8 @@ public final class DateUtil extends DateUtils { ...@@ -154,4 +154,8 @@ public final class DateUtil extends DateUtils {
154 return toDate(localDateTime); 154 return toDate(localDateTime);
155 } 155 }
156 156
157 + public static LocalDate toLocalDate(long timestamp) {
158 + return Instant.ofEpochMilli(timestamp).atZone(CHINA_ZONE).toLocalDate();
159 + }
160 +
157 } 161 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -19,6 +19,7 @@ service EnterpriseResourceTagServiceRpc { ...@@ -19,6 +19,7 @@ service EnterpriseResourceTagServiceRpc {
19 rpc GetUsersByTagId (UsersGetByTagIdRequest) returns (UsersGetByTagIdResponse) {} 19 rpc GetUsersByTagId (UsersGetByTagIdRequest) returns (UsersGetByTagIdResponse) {}
20 rpc CreateTag (TagCreationRpcRequest) returns (TagCreationRpcResponse) {} 20 rpc CreateTag (TagCreationRpcRequest) returns (TagCreationRpcResponse) {}
21 rpc AddResourcesToTag (AddResourcesToTagRpcRequest) returns (AddResourcesToTagRpcResponse) {} 21 rpc AddResourcesToTag (AddResourcesToTagRpcRequest) returns (AddResourcesToTagRpcResponse) {}
22 + rpc GetOperatorIdsByStallId (GetOperatorIdsByStallIdRpcRequest) returns (GetOperatorIdsByStallIdRpcResponse) {}
22 } 23 }
23 24
24 message TagCreationRpcRequest { 25 message TagCreationRpcRequest {
...@@ -203,3 +204,12 @@ message AddResourcesToTagRpcRequest { ...@@ -203,3 +204,12 @@ message AddResourcesToTagRpcRequest {
203 message AddResourcesToTagRpcResponse { 204 message AddResourcesToTagRpcResponse {
204 bool isSuccess = 1; 205 bool isSuccess = 1;
205 } 206 }
207 +
208 +message GetOperatorIdsByStallIdRpcRequest {
209 + int32 enterpriseId = 1;
210 + int32 stallId = 2;
211 +}
212 +
213 +message GetOperatorIdsByStallIdRpcResponse {
214 + repeated int32 operatorIds = 1;
215 +}
...\ No newline at end of file ...\ No newline at end of file
......