TopologicalCommonController.java 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. package com.ruoyi.demo.controller;
  2. import cn.hutool.json.JSONString;
  3. import com.ruoyi.common.annotation.Log;
  4. import com.ruoyi.common.core.domain.R;
  5. import com.ruoyi.common.helper.LoginHelper;
  6. import com.ruoyi.common.utils.JsonUtils;
  7. import com.ruoyi.demo.constant.RedisContant;
  8. import com.ruoyi.demo.entity.WdInfo;
  9. import com.ruoyi.demo.entity.bo.PointBo;
  10. import com.ruoyi.demo.entity.vo.TopologicalWdAceeptVo;
  11. import com.ruoyi.demo.service.TopologicalCommonService;
  12. import com.ruoyi.demo.service.WdInfoService;
  13. import io.swagger.v3.oas.models.security.SecurityScheme;
  14. import lombok.extern.slf4j.Slf4j;
  15. import org.springframework.beans.factory.annotation.Autowired;
  16. import org.springframework.data.geo.Point;
  17. import org.springframework.data.redis.core.RedisTemplate;
  18. import org.springframework.http.MediaType;
  19. import org.springframework.web.bind.annotation.RequestMapping;
  20. import org.springframework.web.bind.annotation.RestController;
  21. import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
  22. import java.io.IOException;
  23. import java.util.HashMap;
  24. import java.util.List;
  25. import java.util.Map;
  26. import java.util.concurrent.ConcurrentHashMap;
  27. import java.util.concurrent.TimeUnit;
  28. /**
  29. * 点位评估-基本功能
  30. */
  31. @RestController
  32. @RequestMapping("/poi/common")
  33. @Slf4j
  34. public class TopologicalCommonController {
  35. @Autowired
  36. TopologicalCommonService topologicalCommonService;
  37. @Autowired
  38. WdInfoService wdInfoService;
  39. @Autowired
  40. RedisTemplate redisTemplate;
  41. /**
  42. * SSE连接传输
  43. */
  44. private static Map<Long, SseEmitter> sseCache = new ConcurrentHashMap<>();
  45. /**
  46. * 搜索栏——前缀查询
  47. * @param searchText 搜索关键字
  48. * @param size 返回数量
  49. * @return
  50. */
  51. @RequestMapping("/prefixSearch")
  52. public R prefixSearch(String searchText,Integer size){
  53. List<WdInfo> wdInfos = topologicalCommonService.prefixSearch(searchText,size);
  54. return R.ok(wdInfos);
  55. }
  56. /**
  57. * 获取半径范围下拉框
  58. * @return
  59. */
  60. @RequestMapping("/range")
  61. public R range(){
  62. HashMap hashMap = new HashMap<>();
  63. hashMap.put("500m",500);
  64. hashMap.put("1km",1000);
  65. hashMap.put("2km",2000);
  66. return R.ok(hashMap);
  67. }
  68. /**
  69. * 获取中心点相邻点坐标(使用SSE连接)
  70. * @param topologicalWdAceeptVo 周边网点接受体
  71. * @return
  72. * @throws IOException
  73. */
  74. @RequestMapping(path = "/map",produces = {MediaType.TEXT_EVENT_STREAM_VALUE})
  75. public SseEmitter map(TopologicalWdAceeptVo topologicalWdAceeptVo) throws IOException {
  76. String md5 = topologicalWdAceeptVo.getHash();
  77. //2.查看redis中是否存在有缓存
  78. List<PointBo> wdCount = (List<PointBo>) redisTemplate.boundHashOps(RedisContant.TOPOLOGICAL_COMMON_MAP).get(md5);
  79. if (wdCount != null) {
  80. SseEmitter sseEmitter = getSseEmitter(LoginHelper.getUserId());
  81. sendFragment(sseEmitter,wdCount);
  82. return sseEmitter;
  83. }
  84. List<PointBo> map = topologicalCommonService.map(topologicalWdAceeptVo);
  85. redisTemplate.boundHashOps(RedisContant.TOPOLOGICAL_COMMON_MAP).put(md5,map);
  86. redisTemplate.expire(RedisContant.TOPOLOGICAL_COMMON_MAP,RedisContant.TOPOLOGICAL_COMMON_MAP_TIME, TimeUnit.MINUTES); //30分钟
  87. SseEmitter sseEmitter = getSseEmitter(LoginHelper.getUserId());
  88. sendFragment(sseEmitter,map);
  89. return sseEmitter;
  90. }
  91. /**
  92. * SSE连接:获取连接实体类SseEmitter
  93. * @param uId 用户Id
  94. * @return
  95. */
  96. public SseEmitter getSseEmitter(Long uId){
  97. SseEmitter sseEmitter = sseCache.get(uId);
  98. if (sseEmitter != null) {
  99. return sseEmitter;
  100. }
  101. // 超时时间设置为3s,用于演示客户端自动重连
  102. // 设置前端的重试时间为1s
  103. SseEmitter sseEmitter1 = new SseEmitter(30000L);
  104. sseCache.put(uId, sseEmitter1);
  105. sseEmitter1.onTimeout(() -> {
  106. log.info(uId + "超时");
  107. sseCache.remove(uId);
  108. });
  109. //sseEmitter.onCompletion(() -> System.out.println("完成!!!"));
  110. return sseEmitter1;
  111. }
  112. /**
  113. * SSE连接:发送信息
  114. * @param sseEmitter
  115. * @param wdCount 点位信息
  116. */
  117. public void sendFragment(SseEmitter sseEmitter,List<PointBo> wdCount){
  118. int size = 1000;
  119. int pages = wdCount.size()%size == 0 ? wdCount.size()/size:wdCount.size()/size+1;
  120. int p1 = 0,p2 = size;
  121. for (int i=0;i<pages;i++){
  122. if (p2 > wdCount.size())
  123. p2 = wdCount.size();
  124. try {
  125. sseEmitter.send(SseEmitter.event().name("map").data(JsonUtils.toJsonString(wdCount.subList(p1,p2))));
  126. p1 = p2;
  127. p2+=size;
  128. } catch (IOException e) {
  129. throw new RuntimeException(e);
  130. }
  131. }
  132. }
  133. }