Browse Source

将 mall-service 的 geo 模块迁移到 content-service

reghao 1 year ago
parent
commit
6c49f41155
45 changed files with 1920 additions and 0 deletions
  1. 27 0
      content/content-api/src/main/java/cn/reghao/tnb/content/api/dto/TaobaoItem.java
  2. 22 0
      content/content-api/src/main/java/cn/reghao/tnb/content/api/dto/geo/JobLoc.java
  3. 48 0
      content/content-api/src/main/java/cn/reghao/tnb/content/api/dto/geo/MallReplyDto.java
  4. 44 0
      content/content-api/src/main/java/cn/reghao/tnb/content/api/dto/geo/MallReplyPhotoDto.java
  5. 109 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/MapController.java
  6. 19 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/db/mapper/BusStationMapper.java
  7. 25 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/db/mapper/CameraPhotoMapper.java
  8. 14 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/db/mapper/GeoEarthMapper.java
  9. 13 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/db/mapper/GeoItemMapper.java
  10. 13 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/db/mapper/GeoPointMapper.java
  11. 17 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/db/mapper/GeoPolygonMapper.java
  12. 15 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/db/mapper/GeoScopeMapper.java
  13. 17 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/db/mapper/JobLocationMapper.java
  14. 18 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/db/mapper/MallReplyMapper.java
  15. 26 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/db/mapper/MallReplyPhotoMapper.java
  16. 30 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/po/BusStation.java
  17. 42 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/po/CameraPhoto.java
  18. 13 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/po/GeoEarth.java
  19. 16 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/po/GeoItem.java
  20. 29 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/po/GeoPoint.java
  21. 27 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/po/GeoPolygon.java
  22. 37 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/po/GeoScope.java
  23. 39 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/po/JobLocation.java
  24. 36 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/po/MallReply.java
  25. 44 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/po/MallReplyPhoto.java
  26. 20 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/vo/MapMarker.java
  27. 39 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/vo/MapPoint.java
  28. 21 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/vo/MarkerInfo.java
  29. 18 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/vo/PublicBus.java
  30. 120 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/service/EarthService.java
  31. 48 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/service/GeoService.java
  32. 40 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/service/JobLocationService.java
  33. 256 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/service/MapService.java
  34. 19 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/util/Gps.java
  35. 174 0
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/util/GpsTransfer.java
  36. 43 0
      content/content-service/src/main/resources/mapper/geo/BusStationMapper.xml
  37. 79 0
      content/content-service/src/main/resources/mapper/geo/CameraPhotoMapper.xml
  38. 17 0
      content/content-service/src/main/resources/mapper/geo/GeoEarthMapper.xml
  39. 16 0
      content/content-service/src/main/resources/mapper/geo/GeoItemMapper.xml
  40. 35 0
      content/content-service/src/main/resources/mapper/geo/GeoPointMapper.xml
  41. 25 0
      content/content-service/src/main/resources/mapper/geo/GeoPolygonMapper.xml
  42. 30 0
      content/content-service/src/main/resources/mapper/geo/GeoScopeMapper.xml
  43. 55 0
      content/content-service/src/main/resources/mapper/geo/JobLocationMapper.xml
  44. 34 0
      content/content-service/src/main/resources/mapper/geo/MallReplyMapper.xml
  45. 91 0
      content/content-service/src/main/resources/mapper/geo/MallReplyPhotoMapper.xml

+ 27 - 0
content/content-api/src/main/java/cn/reghao/tnb/content/api/dto/TaobaoItem.java

@@ -0,0 +1,27 @@
+package cn.reghao.tnb.content.api.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+
+/**
+ * @author reghao
+ * @date 2024-04-16 09:21:44
+ */
+@AllArgsConstructor
+@Setter
+@Getter
+public class TaobaoItem implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private Long itemId;
+    private String itemUrl;
+    private String title;
+    private String picUrl;
+    private Double price;
+    private String monthSale;
+    private Long shopId;
+    private Long sellerId;
+}

+ 22 - 0
content/content-api/src/main/java/cn/reghao/tnb/content/api/dto/geo/JobLoc.java

@@ -0,0 +1,22 @@
+package cn.reghao.tnb.content.api.dto.geo;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author reghao
+ * @date 2024-11-24 14:12:00
+ */
+@AllArgsConstructor
+@Getter
+public class JobLoc {
+    private String companyName;
+    private String issueDate;
+    private String jobHref;
+    private String jobDescribe;
+    private long salaryMin;
+    private long salaryMax;
+    private String salaryStr;
+    private double lat;
+    private double lng;
+}

+ 48 - 0
content/content-api/src/main/java/cn/reghao/tnb/content/api/dto/geo/MallReplyDto.java

@@ -0,0 +1,48 @@
+package cn.reghao.tnb.content.api.dto.geo;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2023-09-01 09:09:35
+ */
+@Setter
+@Getter
+public class MallReplyDto implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @NotNull
+    private Integer itemType;
+    @NotBlank
+    private String itemId;
+    @NotBlank
+    private String replyId;
+    private String replyContent;
+    private String appendContent;
+    private String extra;
+    @NotBlank
+    private String username;
+    @NotBlank
+    private String avatarUrl;
+    @NotEmpty
+    private List<MallReplyPhotoDto> photos;
+
+    public MallReplyDto(int itemType, String itemId, String replyId, String replyContent, String appendContent,
+                        String extra, String username, String avatarUrl) {
+        this.itemType = itemType;
+        this.itemId = itemId;
+        this.replyId = replyId;
+        this.replyContent = replyContent;
+        this.appendContent = appendContent;
+        this.extra = extra;
+        this.username = username;
+        this.avatarUrl = avatarUrl;
+    }
+}

+ 44 - 0
content/content-api/src/main/java/cn/reghao/tnb/content/api/dto/geo/MallReplyPhotoDto.java

@@ -0,0 +1,44 @@
+package cn.reghao.tnb.content.api.dto.geo;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * @author reghao
+ * @date 2023-08-31 10:38:26
+ */
+@NoArgsConstructor
+@Setter
+@Getter
+public class MallReplyPhotoDto implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @NotBlank
+    private String replyId;
+    @NotBlank
+    private String uploadId;
+    @NotNull
+    private Integer channelId;
+    @NotBlank
+    private String photoUrl;
+    private String manufacturer;
+    private String model;
+    private String software;
+    private String shotAt;
+    @NotNull
+    private Double longitude;
+    @NotNull
+    private Double latitude;
+
+    public MallReplyPhotoDto(String replyId, String uploadId, int channelId, String photoUrl) {
+        this.replyId = replyId;
+        this.uploadId = uploadId;
+        this.channelId = channelId;
+        this.photoUrl = photoUrl;
+    }
+}

+ 109 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/MapController.java

@@ -0,0 +1,109 @@
+package cn.reghao.tnb.content.app.geo;
+
+import cn.reghao.jutil.web.WebResult;
+import cn.reghao.tnb.common.db.SelectOption;
+import cn.reghao.tnb.content.api.dto.geo.JobLoc;
+import cn.reghao.tnb.content.api.dto.geo.MallReplyDto;
+import cn.reghao.tnb.content.api.dto.geo.MallReplyPhotoDto;
+import cn.reghao.tnb.content.app.geo.model.vo.MapMarker;
+import cn.reghao.tnb.content.app.geo.model.vo.MapPoint;
+import cn.reghao.tnb.content.app.geo.model.vo.MarkerInfo;
+import cn.reghao.tnb.content.app.geo.service.EarthService;
+import cn.reghao.tnb.content.app.geo.service.JobLocationService;
+import cn.reghao.tnb.content.app.geo.service.MapService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.http.MediaType;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2023-08-31 10:32:28
+ */
+@Api(tags = "地图接口")
+@RestController
+@RequestMapping("/api/mall/map")
+public class MapController {
+    private final MapService mapService;
+    private final EarthService earthService;
+    private final JobLocationService jobLocationService;
+
+    public MapController(MapService mapService, EarthService earthService, JobLocationService jobLocationService) {
+        this.mapService = mapService;
+        this.earthService = earthService;
+        this.jobLocationService = jobLocationService;
+    }
+
+    @ApiOperation(value = "添加工作位置", notes = "N")
+    @PostMapping(value = "/job", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String addJobLocation(@RequestBody JobLoc jobLoc) {
+        jobLocationService.addJobLocation(jobLoc);
+        return WebResult.success();
+    }
+
+    @ApiOperation(value = "检查淘宝商品评论是否存在", notes = "N")
+    @GetMapping(value = "/reply/{replyId}", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String checkReply(@PathVariable("replyId") String replyId) {
+        boolean exist = mapService.checkReplyId(replyId);
+        return WebResult.success(exist);
+    }
+
+    @ApiOperation(value = "添加淘宝商品评论", notes = "N")
+    @PostMapping(value = "/reply", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String addReply(@RequestBody @Validated MallReplyDto mallReplyDto) {
+        mapService.addTmallReply(mallReplyDto);
+        return WebResult.success();
+    }
+
+    @ApiOperation(value = "添加淘宝商品评论中的照片", notes = "N")
+    @PostMapping(value = "/photo", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String addPhoto(@RequestBody List<MallReplyPhotoDto> list) {
+        mapService.addCameraPhotos(list);
+        return WebResult.success();
+    }
+
+    @ApiOperation(value = "获取地图中标记的点", notes = "N")
+    @GetMapping(value = "/markers", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String getMapMarkers(@RequestParam("type") Integer type) {
+        List<MapMarker> list = mapService.getMapMarkers(type);
+        return WebResult.success(list);
+    }
+
+    @ApiOperation(value = "获取 GoogleEarth kml 文件", notes = "N")
+    @GetMapping(value = "/markers/earth", produces = MediaType.APPLICATION_JSON_VALUE)
+    public void getEarthMarkers(@RequestParam("type") Integer type) throws Exception {
+        List<MapMarker> list = mapService.getMapMarkers(type);
+        earthService.getEarthKml(list);
+    }
+
+    @ApiOperation(value = "获取地图中标记点的详情", notes = "N")
+    @GetMapping(value = "/marker", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String getMarkerInfo(@RequestParam("id") String id) {
+        MarkerInfo markerInfo = mapService.getMarkerInfo(id);
+        return WebResult.success(markerInfo);
+    }
+
+    @ApiOperation(value = "获取地图中标记点分类的 select options 列表", notes = "N")
+    @GetMapping(value = "/item", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String getGeoItems() {
+        List<SelectOption> selectOptions = mapService.getGeoItems();
+        return WebResult.success(selectOptions);
+    }
+
+    @ApiOperation(value = "添加一个经纬度坐标", notes = "N")
+    @PostMapping(value = "/point", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String addGeoPoint(@RequestBody @Validated MapPoint mapPoint) {
+        mapService.addGeoPoint(mapPoint);
+        return WebResult.success();
+    }
+
+    @ApiOperation(value = "获取经纬度坐标列表", notes = "N")
+    @GetMapping(value = "/point", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String getGeoPoint() {
+        List list = mapService.getGeoPoints();
+        return WebResult.success(list);
+    }
+}

+ 19 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/db/mapper/BusStationMapper.java

@@ -0,0 +1,19 @@
+package cn.reghao.tnb.content.app.geo.db.mapper;
+
+import cn.reghao.jutil.jdk.db.BaseMapper;
+import cn.reghao.tnb.content.app.geo.model.po.BusStation;
+import cn.reghao.tnb.content.app.geo.model.vo.PublicBus;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2024-08-22 22:30:58
+ */
+@Mapper
+public interface BusStationMapper extends BaseMapper<BusStation> {
+    List<PublicBus> findByLineName(String lineName);
+    List<BusStation> findByStationName(String stationName);
+    List<String> findByGroupLineName();
+}

+ 25 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/db/mapper/CameraPhotoMapper.java

@@ -0,0 +1,25 @@
+package cn.reghao.tnb.content.app.geo.db.mapper;
+
+import cn.reghao.jutil.jdk.db.BaseMapper;
+import cn.reghao.tnb.content.app.geo.model.po.CameraPhoto;
+import cn.reghao.tnb.content.app.geo.model.vo.MapMarker;
+import cn.reghao.tnb.content.app.geo.model.vo.MarkerInfo;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2024-09-07 12:01:54
+ */
+@Mapper
+public interface CameraPhotoMapper extends BaseMapper<CameraPhoto> {
+    void updateSetAlbumId(@Param("objectId") String objectId, @Param("albumId") Long albumId);
+
+    List<MapMarker> findByGeoGroup(int pageSize);
+    List<MapMarker> findByWestGeoGroup(int pageSize);
+    List<MapMarker> findByAlbumId(int pageSize, long albumId);
+    MarkerInfo findMarkerInfoById(String id);
+    CameraPhoto findByObjectId(String objectId);
+}

+ 14 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/db/mapper/GeoEarthMapper.java

@@ -0,0 +1,14 @@
+package cn.reghao.tnb.content.app.geo.db.mapper;
+
+import cn.reghao.jutil.jdk.db.BaseMapper;
+import cn.reghao.tnb.content.app.geo.model.po.GeoEarth;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @author reghao
+ * @date 2023-09-12 11:44:17
+ */
+@Mapper
+public interface GeoEarthMapper extends BaseMapper<GeoEarth> {
+    GeoEarth findByName(String name);
+}

+ 13 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/db/mapper/GeoItemMapper.java

@@ -0,0 +1,13 @@
+package cn.reghao.tnb.content.app.geo.db.mapper;
+
+import cn.reghao.jutil.jdk.db.BaseMapper;
+import cn.reghao.tnb.content.app.geo.model.po.GeoItem;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @author reghao
+ * @date 2024-09-10 14:30:23
+ */
+@Mapper
+public interface GeoItemMapper extends BaseMapper<GeoItem> {
+}

+ 13 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/db/mapper/GeoPointMapper.java

@@ -0,0 +1,13 @@
+package cn.reghao.tnb.content.app.geo.db.mapper;
+
+import cn.reghao.jutil.jdk.db.BaseMapper;
+import cn.reghao.tnb.content.app.geo.model.po.GeoPoint;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @author reghao
+ * @date 2024-09-10 17:37:19
+ */
+@Mapper
+public interface GeoPointMapper extends BaseMapper<GeoPoint> {
+}

+ 17 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/db/mapper/GeoPolygonMapper.java

@@ -0,0 +1,17 @@
+package cn.reghao.tnb.content.app.geo.db.mapper;
+
+import cn.reghao.jutil.jdk.db.BaseMapper;
+import cn.reghao.tnb.content.app.geo.model.po.GeoPolygon;
+import cn.reghao.tnb.content.app.geo.model.vo.MapPoint;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2023-09-12 15:20:49
+ */
+@Mapper
+public interface GeoPolygonMapper extends BaseMapper<GeoPolygon> {
+    List<Integer> findByPoint(MapPoint mapPoint);
+}

+ 15 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/db/mapper/GeoScopeMapper.java

@@ -0,0 +1,15 @@
+package cn.reghao.tnb.content.app.geo.db.mapper;
+
+import cn.reghao.jutil.jdk.db.BaseMapper;
+import cn.reghao.tnb.content.app.geo.model.po.GeoScope;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * @author reghao
+ * @date 2023-09-11 18:09:02
+ */
+@Mapper
+public interface GeoScopeMapper extends BaseMapper<GeoScope> {
+    GeoScope findByName(@Param("name") String name);
+}

+ 17 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/db/mapper/JobLocationMapper.java

@@ -0,0 +1,17 @@
+package cn.reghao.tnb.content.app.geo.db.mapper;
+
+import cn.reghao.jutil.jdk.db.BaseMapper;
+import cn.reghao.tnb.content.app.geo.model.po.JobLocation;
+import cn.reghao.tnb.content.app.geo.model.vo.MapMarker;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2024-11-24 14:18:23
+ */
+@Mapper
+public interface JobLocationMapper extends BaseMapper<JobLocation> {
+    List<MapMarker> findMapMarker();
+}

+ 18 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/db/mapper/MallReplyMapper.java

@@ -0,0 +1,18 @@
+package cn.reghao.tnb.content.app.geo.db.mapper;
+
+import cn.reghao.jutil.jdk.db.BaseMapper;
+import cn.reghao.tnb.content.app.geo.model.po.MallReply;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2023-08-27 13:23:13
+ */
+@Mapper
+public interface MallReplyMapper extends BaseMapper<MallReply> {
+    List<MallReply> findByItemType(int itemType);
+    List<MallReply> findByItemId(String itemId);
+    MallReply findByReplyId(String replyId);
+}

+ 26 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/db/mapper/MallReplyPhotoMapper.java

@@ -0,0 +1,26 @@
+package cn.reghao.tnb.content.app.geo.db.mapper;
+
+import cn.reghao.jutil.jdk.db.BaseMapper;
+import cn.reghao.tnb.content.app.geo.model.po.GeoScope;
+import cn.reghao.tnb.content.app.geo.model.po.MallReplyPhoto;
+import cn.reghao.tnb.content.app.geo.model.vo.MapMarker;
+import cn.reghao.tnb.content.app.geo.model.vo.MarkerInfo;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2023-08-27 13:23:13
+ */
+@Mapper
+public interface MallReplyPhotoMapper extends BaseMapper<MallReplyPhoto> {
+    List<MapMarker> findAllByReplyIdGroup(int pageSize);
+    List<MapMarker> findByReplyIdGroup(int pageSize, int itemType);
+    List<MapMarker> findByGeoScope(@Param("pageSize") int pageSize,
+                                   @Param("itemType") int itemType,
+                                   @Param("geoScope") GeoScope geoScope);
+    List<MapMarker> findByWestChina(int pageSize, int itemType);
+    MarkerInfo findMarkerInfoById(int id);
+}

+ 30 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/po/BusStation.java

@@ -0,0 +1,30 @@
+package cn.reghao.tnb.content.app.geo.model.po;
+
+import cn.reghao.jutil.jdk.db.BaseObject;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+/**
+ * @author reghao
+ * @date 2024-08-22 22:15:09
+ */
+@NoArgsConstructor
+@Setter
+@Getter
+public class BusStation extends BaseObject<Integer> {
+    private long lng;
+    private long lat;
+    private String stationName;
+    private int pm;
+    private int tid;
+    private String lineName;
+
+    public BusStation(long lng, long lat, String stationName, int pm, int tid) {
+        this.lng = lng;
+        this.lat = lat;
+        this.stationName = stationName;
+        this.pm = pm;
+        this.tid = tid;
+    }
+}

+ 42 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/po/CameraPhoto.java

@@ -0,0 +1,42 @@
+package cn.reghao.tnb.content.app.geo.model.po;
+
+import cn.reghao.jutil.jdk.db.BaseObject;
+import cn.reghao.tnb.content.api.dto.geo.MallReplyPhotoDto;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * @author reghao
+ * @date 2024-09-07 12:01:03
+ */
+@NoArgsConstructor
+@Setter
+@Getter
+public class CameraPhoto extends BaseObject<Integer> {
+    private Long albumId;
+    private String objectId;
+    private Integer channelId;
+    private String photoUrl;
+    private String manufacturer;
+    private String model;
+    private String software;
+    private LocalDateTime shotAt;
+    private BigDecimal longitude;
+    private BigDecimal latitude;
+
+    public CameraPhoto(MallReplyPhotoDto mallReplyPhotoDto) {
+        this.albumId = 0L;
+        this.objectId = mallReplyPhotoDto.getUploadId();
+        this.channelId = mallReplyPhotoDto.getChannelId();
+        this.photoUrl = mallReplyPhotoDto.getPhotoUrl();
+        this.manufacturer = mallReplyPhotoDto.getManufacturer();
+        this.model = mallReplyPhotoDto.getModel();
+        this.software = mallReplyPhotoDto.getSoftware();
+        this.longitude = BigDecimal.valueOf(mallReplyPhotoDto.getLongitude());
+        this.latitude = BigDecimal.valueOf(mallReplyPhotoDto.getLatitude());
+    }
+}

+ 13 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/po/GeoEarth.java

@@ -0,0 +1,13 @@
+package cn.reghao.tnb.content.app.geo.model.po;
+
+import lombok.Getter;
+
+/**
+ * @author reghao
+ * @date 2023-09-12 11:43:50
+ */
+@Getter
+public class GeoEarth {
+    private String name;
+    private String template;
+}

+ 16 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/po/GeoItem.java

@@ -0,0 +1,16 @@
+package cn.reghao.tnb.content.app.geo.model.po;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author reghao
+ * @date 2024-09-10 14:29:32
+ */
+@AllArgsConstructor
+@Getter
+public class GeoItem {
+    private Integer id;
+    private String name;
+    private Integer total;
+}

+ 29 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/po/GeoPoint.java

@@ -0,0 +1,29 @@
+package cn.reghao.tnb.content.app.geo.model.po;
+
+import cn.reghao.jutil.jdk.db.BaseObject;
+import cn.reghao.tnb.common.auth.UserContext;
+import cn.reghao.tnb.content.app.geo.model.vo.MapPoint;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+
+/**
+ * @author reghao
+ * @date 2024-09-10 17:37:07
+ */
+@NoArgsConstructor
+@Getter
+public class GeoPoint extends BaseObject<Integer> {
+    // 经度
+    private BigDecimal longitude;
+    // 纬度
+    private BigDecimal latitude;
+    private Long createBy;
+
+    public GeoPoint(MapPoint mapPoint) {
+        this.longitude = BigDecimal.valueOf(mapPoint.getLng());
+        this.latitude = BigDecimal.valueOf(mapPoint.getLat());
+        this.createBy = UserContext.getUser();
+    }
+}

+ 27 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/po/GeoPolygon.java

@@ -0,0 +1,27 @@
+package cn.reghao.tnb.content.app.geo.model.po;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+/**
+ * @author reghao
+ * @date 2023-09-12 15:19:41
+ */
+@NoArgsConstructor
+@AllArgsConstructor
+@Setter
+@Getter
+public class GeoPolygon {
+    private Integer id;
+    private Integer pid;
+    private Integer deep;
+    private String name;
+    private String extName;
+    private BigDecimal longitude;
+    private BigDecimal latitude;
+    private String polygon;
+}

+ 37 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/po/GeoScope.java

@@ -0,0 +1,37 @@
+package cn.reghao.tnb.content.app.geo.model.po;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * @author reghao
+ * @date 2023-09-11 17:18:31
+ */
+@NoArgsConstructor
+@AllArgsConstructor
+@Setter
+@Getter
+public class GeoScope implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private int id;
+    private int pid;
+    private String name;
+    // 起始经度
+    private BigDecimal lngEast;
+    private BigDecimal lngWest;
+    // 起始纬度
+    private BigDecimal latNorth;
+    private BigDecimal latSouth;
+
+    public GeoScope(int id, int pid, String name) {
+        this.id = id;
+        this.pid = pid;
+        this.name = name;
+    }
+}

+ 39 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/po/JobLocation.java

@@ -0,0 +1,39 @@
+package cn.reghao.tnb.content.app.geo.model.po;
+
+import cn.reghao.jutil.jdk.db.BaseObject;
+import cn.reghao.tnb.content.api.dto.geo.JobLoc;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * @author reghao
+ * @date 2024-11-24 14:08:53
+ */
+@NoArgsConstructor
+@Getter
+public class JobLocation extends BaseObject<Integer> {
+    private String companyName;
+    private LocalDateTime issueDate;
+    private String jobHref;
+    private String jobDescribe;
+    private long salaryMin;
+    private long salaryMax;
+    private String salaryStr;
+    private BigDecimal longitude;
+    private BigDecimal latitude;
+
+    public JobLocation(JobLoc jobLoc, LocalDateTime issueDate) {
+        this.companyName = jobLoc.getCompanyName();
+        this.issueDate = issueDate;
+        this.jobHref = jobLoc.getJobHref();
+        this.jobDescribe = jobLoc.getJobDescribe();
+        this.salaryMin = jobLoc.getSalaryMin();
+        this.salaryMax = jobLoc.getSalaryMax();
+        this.salaryStr = jobLoc.getSalaryStr();
+        this.longitude = BigDecimal.valueOf(jobLoc.getLng());
+        this.latitude = BigDecimal.valueOf(jobLoc.getLat());
+    }
+}

+ 36 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/po/MallReply.java

@@ -0,0 +1,36 @@
+package cn.reghao.tnb.content.app.geo.model.po;
+
+import cn.reghao.jutil.jdk.db.BaseObject;
+import cn.reghao.tnb.content.api.dto.geo.MallReplyDto;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author reghao
+ * @date 2023-08-31 16:56:17
+ */
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+public class MallReply extends BaseObject<Integer> {
+    private Integer itemType;
+    private String itemId;
+    private String replyId;
+    private String replyContent;
+    private String appendContent;
+    private String extra;
+    private String username;
+    private String avatarUrl;
+
+    public MallReply(MallReplyDto mallReplyDto) {
+        this.itemType = mallReplyDto.getItemType();
+        this.itemId = mallReplyDto.getItemId();
+        this.replyId = mallReplyDto.getReplyId();
+        this.replyContent = mallReplyDto.getReplyContent();
+        this.appendContent = mallReplyDto.getAppendContent();
+        this.extra = mallReplyDto.getExtra();
+        this.username = mallReplyDto.getUsername();
+        this.avatarUrl = mallReplyDto.getAvatarUrl();
+    }
+}

+ 44 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/po/MallReplyPhoto.java

@@ -0,0 +1,44 @@
+package cn.reghao.tnb.content.app.geo.model.po;
+
+import cn.reghao.jutil.jdk.db.BaseObject;
+import cn.reghao.tnb.content.api.dto.geo.MallReplyPhotoDto;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * @author reghao
+ * @date 2023-08-31 16:56:59
+ */
+@NoArgsConstructor
+@Setter
+@Getter
+public class MallReplyPhoto extends BaseObject<Integer> {
+    private String replyId;
+    private String uploadId;
+    private Integer channelId;
+    private String photoUrl;
+    private String manufacturer;
+    private String model;
+    private String software;
+    private LocalDateTime shotAt;
+    private BigDecimal longitude;
+    private BigDecimal latitude;
+    private transient GeoPoint geoPoint;
+    //private String geohash;
+
+    public MallReplyPhoto(MallReplyPhotoDto mallReplyPhotoDto) {
+        this.replyId = mallReplyPhotoDto.getReplyId();
+        this.uploadId = mallReplyPhotoDto.getUploadId();
+        this.channelId = mallReplyPhotoDto.getChannelId();
+        this.photoUrl = mallReplyPhotoDto.getPhotoUrl();
+        this.manufacturer = mallReplyPhotoDto.getManufacturer();
+        this.model = mallReplyPhotoDto.getModel();
+        this.software = mallReplyPhotoDto.getSoftware();
+        this.longitude = BigDecimal.valueOf(mallReplyPhotoDto.getLongitude());
+        this.latitude = BigDecimal.valueOf(mallReplyPhotoDto.getLatitude());
+    }
+}

+ 20 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/vo/MapMarker.java

@@ -0,0 +1,20 @@
+package cn.reghao.tnb.content.app.geo.model.vo;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+/**
+ * 百度地图标记
+ *
+ * @author reghao
+ * @date 2023-08-31 10:38:26
+ */
+@NoArgsConstructor
+@Setter
+@Getter
+public class MapMarker {
+    private String id;
+    private String title;
+    private MapPoint position;
+}

+ 39 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/vo/MapPoint.java

@@ -0,0 +1,39 @@
+package cn.reghao.tnb.content.app.geo.model.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+
+/**
+ * @author reghao
+ * @date 2023-08-31 17:43:27
+ */
+@NoArgsConstructor
+@AllArgsConstructor
+@Setter
+@Getter
+public class MapPoint {
+    // 经度
+    private BigDecimal lng1;
+    // 纬度
+    private BigDecimal lat1;
+    @NotNull
+    private Double lng;
+    @NotNull
+    private Double lat;
+    private Long timestamp;
+
+    /*public GeoPoint(String lng, String lat) {
+        this.lng = new BigDecimal(lng);
+        this.lat = new BigDecimal(lat);
+    }*/
+
+    /*@Override
+    public String toString() {
+        return "{"+lng+","+lat+"}";
+    }*/
+}

+ 21 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/vo/MarkerInfo.java

@@ -0,0 +1,21 @@
+package cn.reghao.tnb.content.app.geo.model.vo;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author reghao
+ * @date 2023-08-31 10:38:13
+ */
+@Setter
+@Getter
+public class MarkerInfo {
+    private String itemId;
+    private String replyId;
+    private String sku;
+    private String replyContent;
+    private String appendContent;
+    private String uploadId;
+    private Integer channelId;
+    private String photoUrl;
+}

+ 18 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/vo/PublicBus.java

@@ -0,0 +1,18 @@
+package cn.reghao.tnb.content.app.geo.model.vo;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+/**
+ * @author reghao
+ * @date 2024-09-05 21:59:48
+ */
+@NoArgsConstructor
+@Setter
+@Getter
+public class PublicBus {
+    private String lineName;
+    private int pos;
+    private String stationName;
+}

+ 120 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/service/EarthService.java

@@ -0,0 +1,120 @@
+package cn.reghao.tnb.content.app.geo.service;
+
+import cn.reghao.jutil.web.ServletUtil;
+import cn.reghao.tnb.content.app.geo.db.mapper.GeoEarthMapper;
+import cn.reghao.tnb.content.app.geo.model.po.GeoEarth;
+import cn.reghao.tnb.content.app.geo.model.vo.MapMarker;
+import org.dom4j.Document;
+import org.dom4j.Element;
+import org.dom4j.io.OutputFormat;
+import org.dom4j.io.SAXReader;
+import org.dom4j.io.XMLWriter;
+import org.springframework.stereotype.Service;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * GoogleEarth kml 文件
+ *
+ * @author reghao
+ * @date 2023-09-12 11:11:14
+ */
+@Service
+public class EarthService {
+    private final GeoEarthMapper geoEarthMapper;
+
+    public EarthService(GeoEarthMapper geoEarthMapper) {
+        this.geoEarthMapper = geoEarthMapper;
+    }
+
+    public void getEarthKml(List<MapMarker> list) throws Exception {
+        GeoEarth geoEarth = geoEarthMapper.findByName("default");
+        String template = geoEarth.getTemplate();
+        ByteArrayInputStream inputStream = new ByteArrayInputStream(template.getBytes(StandardCharsets.UTF_8));
+        SAXReader reader = new SAXReader();
+        Document document = reader.read(inputStream);
+        Iterator<Element> iterator = document.getRootElement().elementIterator();
+        // 根元素 <Document></Document>
+        Element root = iterator.next();
+        root.addElement("name").setText("exports");
+        Element folder = addFolder(root, "dir1");
+        for (MapMarker mapMarker : list) {
+            addPlaceMark(folder, mapMarker);
+        }
+
+        /*Element folder1 = addFolder(root, "目录2");
+        for (MapMarker mapMarker : list.subList(101, 200)) {
+            addPlaceMark(folder1, mapMarker);
+        }
+        Element folder2 = addFolder(root, "目录3");
+        for (MapMarker mapMarker : list.subList(201, 300)) {
+            addPlaceMark(folder2, mapMarker);
+        }*/
+
+        File out = new File("/home/reghao/Downloads/places2.kml");
+        OutputStream outputStream = new FileOutputStream(out);
+        //ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        OutputFormat format = OutputFormat.createPrettyPrint();
+        format.setEncoding(StandardCharsets.UTF_8.name());
+        XMLWriter writer = new XMLWriter(outputStream, format);
+        writer.setEscapeText(false);
+        writer.write(document);
+        writer.close();
+
+        /*ByteArrayInputStream bais = new ByteArrayInputStream(outputStream.toByteArray());
+        download("GoogleEarth.kml", bais);*/
+    }
+
+    private Element addFolder(Element element, String name) {
+        Element folder = element.addElement("Folder");
+        folder.addElement("name").setText(name);
+        folder.addElement("visibility").setText("0");
+        // 目录关闭
+        folder.addElement("open").setText("0");
+        return folder;
+    }
+
+    private void addPlaceMark(Element element, MapMarker mapMarker) {
+        String name = mapMarker.getTitle();
+        String lat = mapMarker.getPosition().getLat().toString();
+        String lng = mapMarker.getPosition().getLng().toString();
+
+        Element placeMark = element.addElement("Placemark");
+        placeMark.addElement("name").setText(name);
+        placeMark.addElement("visibility").setText("0");
+        Element point = placeMark.addElement("Point");
+        Element coordinates = point.addElement("coordinates");
+        // 坐标关闭
+        coordinates.setText(lng + " " + lat + ",0");
+    }
+
+    public void download(String filename, InputStream in) throws IOException {
+        HttpServletResponse response = ServletUtil.getResponse();
+        prepareResponse(filename, response);
+        download(in, response.getOutputStream());
+    }
+
+    private void prepareResponse(String filename, HttpServletResponse response) throws UnsupportedEncodingException {
+        response.setHeader("content-type", "application/octet-stream");
+        response.setContentType("application/octet-stream");
+        response.setHeader("Content-Disposition",
+                "attachment;filename=" + URLEncoder.encode(filename, StandardCharsets.UTF_8.toString()));
+    }
+
+    private void download(InputStream in, OutputStream out) throws IOException {
+        // 1MiB
+        byte[] buffer = new byte[1024*1024];
+        int i = in.read(buffer);
+        while (i != -1) {
+            out.write(buffer, 0, i);
+            i = in.read(buffer);
+        }
+        in.close();
+        out.close();
+    }
+}

+ 48 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/service/GeoService.java

@@ -0,0 +1,48 @@
+package cn.reghao.tnb.content.app.geo.service;
+
+import cn.reghao.jutil.jdk.text.TextFile;
+import cn.reghao.tnb.content.app.geo.model.po.GeoPolygon;
+
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author reghao
+ * @date 2024-09-09 15:39:46
+ */
+public class GeoService {
+    public static void main(String[] args) {
+        TextFile textFile = new TextFile();
+
+        String filePath = "/home/reghao/Downloads/geo/ok_geo.csv";
+        List<String> list = textFile.read(filePath);
+        Map<Integer, GeoPolygon> map = new HashMap<>();
+        for (int i = 1; i < list.size(); i++) {
+            String line = list.get(i);
+            String[] arr = line.split(",\"");
+            String[] arr1 = arr[0].split(",");
+
+            if (arr1[0].startsWith("71")) {
+                continue;
+            }
+
+            Integer id = Integer.parseInt(arr1[0]);
+            Integer pid = Integer.parseInt(arr1[1]);
+            Integer deep = Integer.parseInt(arr1[2]);
+            String name = arr[1];
+            String extPath = arr[2];
+            String geo = arr[3];
+            String[] geoArr = geo.replace("\"", "").split(" ");
+            BigDecimal lat = BigDecimal.valueOf(Double.parseDouble(geoArr[0]));
+            BigDecimal lng = BigDecimal.valueOf(Double.parseDouble(geoArr[1]));
+            String polygon = arr[4];
+
+            GeoPolygon geoPolygon = new GeoPolygon(id, pid, deep, name, extPath, lat, lng, polygon);
+            map.put(id, geoPolygon);
+        }
+
+        System.out.println();
+    }
+}

+ 40 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/service/JobLocationService.java

@@ -0,0 +1,40 @@
+package cn.reghao.tnb.content.app.geo.service;
+
+import cn.reghao.jutil.jdk.converter.DateTimeConverter;
+import cn.reghao.tnb.content.api.dto.geo.JobLoc;
+import cn.reghao.tnb.content.app.geo.db.mapper.JobLocationMapper;
+import cn.reghao.tnb.content.app.geo.model.po.JobLocation;
+import cn.reghao.tnb.content.app.geo.model.vo.MapMarker;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2024-11-24 14:17:52
+ */
+@Service
+public class JobLocationService {
+    private final JobLocationMapper jobLocationMapper;
+
+    public JobLocationService(JobLocationMapper jobLocationMapper) {
+        this.jobLocationMapper = jobLocationMapper;
+    }
+
+    public void addJobLocation(JobLoc jobLoc) {
+        LocalDateTime issueDate = LocalDateTime.MIN;
+        try {
+            issueDate = DateTimeConverter.localDateTime2(jobLoc.getIssueDate());
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        JobLocation jobLocation = new JobLocation(jobLoc, issueDate);
+        jobLocationMapper.save(jobLocation);
+    }
+
+    public List<MapMarker> getMapMarks() {
+        return jobLocationMapper.findMapMarker();
+    }
+}

+ 256 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/service/MapService.java

@@ -0,0 +1,256 @@
+package cn.reghao.tnb.content.app.geo.service;
+
+import cn.reghao.file.api.iface.OssService;
+import cn.reghao.jutil.jdk.converter.DateTimeConverter;
+import cn.reghao.jutil.jdk.serializer.JsonConverter;
+import cn.reghao.tnb.common.db.SelectOption;
+import cn.reghao.tnb.content.api.dto.geo.MallReplyDto;
+import cn.reghao.tnb.content.api.dto.geo.MallReplyPhotoDto;
+import cn.reghao.tnb.content.app.geo.db.mapper.*;
+import cn.reghao.tnb.content.app.geo.model.po.CameraPhoto;
+import cn.reghao.tnb.content.app.geo.model.po.GeoPoint;
+import cn.reghao.tnb.content.app.geo.model.po.MallReply;
+import cn.reghao.tnb.content.app.geo.model.po.MallReplyPhoto;
+import cn.reghao.tnb.content.app.geo.model.vo.MapMarker;
+import cn.reghao.tnb.content.app.geo.model.vo.MapPoint;
+import cn.reghao.tnb.content.app.geo.model.vo.MarkerInfo;
+import com.google.gson.JsonObject;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDateTime;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+/**
+ * @author reghao
+ * @date 2023-08-31 17:49:48
+ */
+@Slf4j
+@Service
+public class MapService {
+    @DubboReference(check = false, retries = 0)
+    private OssService ossService;
+
+    private final MallReplyMapper mallReplyMapper;
+    private final MallReplyPhotoMapper mallReplyPhotoMapper;
+    private final GeoScopeMapper geoScopeMapper;
+    private final GeoItemMapper geoItemMapper;
+    private final GeoPointMapper geoPointMapper;
+    private final CameraPhotoMapper cameraPhotoMapper;
+    private JobLocationService jobLocationService;
+
+    public MapService(MallReplyMapper mallReplyMapper, MallReplyPhotoMapper mallReplyPhotoMapper,
+                      GeoScopeMapper geoScopeMapper, GeoItemMapper geoItemMapper,
+                      GeoPointMapper geoPointMapper, CameraPhotoMapper cameraPhotoMapper,
+                      JobLocationService jobLocationService) {
+        this.mallReplyMapper = mallReplyMapper;
+        this.mallReplyPhotoMapper = mallReplyPhotoMapper;
+        this.geoScopeMapper = geoScopeMapper;
+        this.geoItemMapper = geoItemMapper;
+        this.geoPointMapper = geoPointMapper;
+        this.cameraPhotoMapper = cameraPhotoMapper;
+        this.jobLocationService = jobLocationService;
+    }
+
+    public boolean checkReplyId(String replyId) {
+        MallReply mallReply = mallReplyMapper.findByReplyId(replyId);
+        return mallReply != null;
+    }
+
+    public synchronized void addTmallReply(MallReplyDto mallReplyDto) {
+        String replyId = mallReplyDto.getReplyId();
+        MallReply mallReply = mallReplyMapper.findByReplyId(replyId);
+        if (mallReply != null) {
+            log.info("{} 已存在", replyId);
+            return;
+        }
+
+        mallReply = new MallReply(mallReplyDto);
+        List<MallReplyPhoto> list = mallReplyDto.getPhotos().stream()
+                .map(mallReplyPhotoDto -> {
+                    MallReplyPhoto mallReplyPhoto = new MallReplyPhoto(mallReplyPhotoDto);
+                    try {
+                        String shotAtStr = mallReplyPhotoDto.getShotAt();
+                        if (shotAtStr != null) {
+                            LocalDateTime shotAt = DateTimeConverter.localDateTime2(mallReplyPhotoDto.getShotAt());
+                            mallReplyPhoto.setShotAt(shotAt);
+                        }
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+
+                    return mallReplyPhoto;
+                })
+                .collect(Collectors.toList());
+        if (!list.isEmpty()) {
+            saveTmallReply(mallReply, list);
+        }
+    }
+
+    public void addCameraPhotos(List<MallReplyPhotoDto> list) {
+        List<CameraPhoto> locations = list.stream().map(mallReplyPhotoDto -> {
+            CameraPhoto cameraPhoto = new CameraPhoto(mallReplyPhotoDto);
+            try {
+                String shotAtStr = mallReplyPhotoDto.getShotAt();
+                if (shotAtStr != null) {
+                    LocalDateTime shotAt = DateTimeConverter.localDateTime2(mallReplyPhotoDto.getShotAt());
+                    cameraPhoto.setShotAt(shotAt);
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            return cameraPhoto;
+        }).collect(Collectors.toList());
+        if (!locations.isEmpty()) {
+            cameraPhotoMapper.saveAll(locations);
+        }
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    public void saveTmallReply(MallReply mallReply, List<MallReplyPhoto> list) {
+        mallReplyMapper.save(mallReply);
+        mallReplyPhotoMapper.saveAll(list);
+    }
+
+    public List<MapMarker> getMapMarkers(int itemType) {
+        int pageSize = 1000;
+        if (itemType == 1) {
+            List<MapMarker> list = mallReplyPhotoMapper.findAllByReplyIdGroup(pageSize);
+            //List<MapMarker> list = mallReplyPhotoMapper.findAllByGeoScope(pageSize, geoScope.getId());
+            return list;
+        } else if (itemType == 2) {
+            List<MapMarker> list = mallReplyPhotoMapper.findByWestChina(pageSize, itemType);
+            //List<MapMarker> list = mallReplyPhotoMapper.findByGeoScope(pageSize, itemType, geoScope1);
+            setMarkTitle(list);
+            return list;
+        } else if (itemType == 3) {
+            List<MapMarker> list = mallReplyPhotoMapper.findByReplyIdGroup(pageSize, itemType);
+            return list;
+        } else if (itemType == 4) {
+            List<MapMarker> list = mallReplyPhotoMapper.findByReplyIdGroup(pageSize, itemType);
+            return list;
+        } else if (itemType == 5) {
+            List<MapMarker> list = cameraPhotoMapper.findByWestGeoGroup(pageSize);
+            return list;
+        } else if (itemType == 6) {
+            List<MapMarker> list = cameraPhotoMapper.findByAlbumId(pageSize, 0);
+            list.forEach(mapMarker -> {
+                String objectId = mapMarker.getId();
+            });
+            return list;
+        } else if (itemType == 7) {
+            List<MapMarker> list = jobLocationService.getMapMarks();
+            return list;
+        }
+
+        return Collections.emptyList();
+    }
+
+    private void setMarkTitle(List<MapMarker> list) {
+        list.forEach(mapMarker -> {
+            String title = mapMarker.getTitle();
+            if (title == null) {
+                mapMarker.setTitle("标记");
+                return;
+            }
+
+            mapMarker.setTitle(getFormattedTitle1(title));
+        });
+    }
+
+    private String getFormattedTitle1(String title) {
+        String extra1 = null;
+        if (title.startsWith("{")) {
+            JsonObject jsonObject = JsonConverter.jsonToJsonElement(title).getAsJsonObject();
+            extra1 = jsonObject.get("尺码").getAsString();
+        } else {
+            extra1 = title.split("尺码:")[1];
+            String[] arr = title.split("&nbsp;&nbsp");
+            for (String str : arr) {
+                if (str.startsWith("尺码")) {
+                    extra1 = str.split(":")[1];
+                    break;
+                }
+            }
+        }
+        return extra1;
+    }
+
+    public MarkerInfo getMarkerInfo(String id) {
+        MarkerInfo markerInfo;
+        if (isInteger(id)) {
+            markerInfo = mallReplyPhotoMapper.findMarkerInfoById(Integer.parseInt(id));
+        } else {
+            markerInfo = cameraPhotoMapper.findMarkerInfoById(id);
+        }
+
+        int channelId = markerInfo.getChannelId();
+        if (channelId != 0) {
+            String uploadId = markerInfo.getUploadId();
+            try {
+                String signedUrl = ossService.getSignedUrl(channelId, uploadId);
+                if (signedUrl != null) {
+                    markerInfo.setPhotoUrl(signedUrl);
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+        return markerInfo;
+    }
+
+    private boolean isInteger(String str) {
+        Pattern pattern = Pattern.compile("^[-+]?[\\d]*$");
+        return pattern.matcher(str).matches();
+    }
+
+    public List<SelectOption> getGeoItems() {
+        return geoItemMapper.findAll().stream()
+                .map(geoItem -> {
+                    String name = geoItem.getName();
+                    int id = geoItem.getId();
+                    return new SelectOption(name, id);
+                }).collect(Collectors.toList());
+    }
+
+    public MarkerInfo getMarkerInfo(int id) {
+        MarkerInfo markerInfo = mallReplyPhotoMapper.findMarkerInfoById(id);
+        int channelId = markerInfo.getChannelId();
+        String uploadId = markerInfo.getUploadId();
+        try {
+            String signedUrl = ossService.getSignedUrl(channelId, uploadId);
+            if (signedUrl != null) {
+                markerInfo.setPhotoUrl(signedUrl);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return markerInfo;
+    }
+
+    public void addGeoPoint(MapPoint mapPoint) {
+        GeoPoint geoPoint = new GeoPoint(mapPoint);
+        geoPointMapper.save(geoPoint);
+    }
+
+    public List getGeoPoints() {
+        List<GeoPoint> list = geoPointMapper.findAll();
+        List<List<Double>> list1 = list.stream().map(geoPoint -> {
+            Double lng = geoPoint.getLongitude().doubleValue();
+            Double lat = geoPoint.getLatitude().doubleValue();
+            return List.of(lng, lat);
+        }).collect(Collectors.toList());
+
+        Map<String, List<List<Double>>> map = new HashMap<>();
+        map.put("path", list1);
+        return List.of(map);
+    }
+}

+ 19 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/util/Gps.java

@@ -0,0 +1,19 @@
+package cn.reghao.tnb.content.app.geo.util;
+
+/**
+ * @author reghao
+ * @date 2024-09-13 22:49:27
+ */
+public class Gps{
+    double lat,lng;
+    public Gps() {
+    }
+    public Gps(double lat,double lng){
+        this.lat = lat;
+        this.lng = lng;
+    }
+    @Override
+    public String toString() {
+        return "{"+lng+","+lat+"}";
+    }
+}

+ 174 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/util/GpsTransfer.java

@@ -0,0 +1,174 @@
+package cn.reghao.tnb.content.app.geo.util;
+
+/***
+ * wgs84 84年提出,大地坐标,也是原始坐标。
+ * gcj02 02年提出,火星坐标,经过加密算法。大多数非百度中国地图厂商基本都是使用的火星坐标:高德,腾讯,谷歌中国cn
+ * bd09  09年提出,百度坐标,经过火星坐标再次加密,相当于对大地坐标经过了二次加密。百度自己使用
+ * 一般的算法,没有直接bd09->wgs84或者wgs84->bd09,都需要借助wgs84->gcj02或者gcj02->wgs84算法推导。
+ */
+public class GpsTransfer {
+    //π的定义
+    public static double pi = 3.1415926535897932384626;
+    //椭球长半径,依据克拉索索夫斯基椭球系数计算
+    public static double a = 6378245.0;
+    //第一偏心率的平方
+    public static double ee = 0.00669342162296594323;
+
+    public static double transformLat(double x, double y) {
+        double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y
+                + 0.2 * Math.sqrt(Math.abs(x));
+        ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
+        ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0;
+        ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0;
+        return ret;
+    }
+
+    public static double transformLng(double x, double y) {
+        double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1
+                * Math.sqrt(Math.abs(x));
+        ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
+        ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0;
+        ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0
+                * pi)) * 2.0 / 3.0;
+        return ret;
+    }
+
+    /***
+     * 判断是否在中国范围之内
+     * @param lat
+     * @param lng
+     * @return
+     */
+    public static boolean outOfChina(double lat, double lng) {
+        if (lng < 72.004 || lng > 137.8347)
+            return true;
+        if (lat < 0.8293 || lat > 55.8271)
+            return true;
+        return false;
+    }
+
+    /***
+     * 把公式部分抽取出来
+     * @param lat
+     * @param lng
+     * @return
+     */
+    public static Gps transform(double lat, double lng) {
+        if (outOfChina(lat, lng)) {
+            return new Gps(lat, lng);
+        }
+        double dLat = transformLat(lng - 105.0, lat - 35.0);
+        double dLng = transformLng(lng - 105.0, lat - 35.0);
+        double radLat = lat / 180.0 * pi;
+        double magic = Math.sin(radLat);
+        magic = 1 - ee * magic * magic;
+        double sqrtMagic = Math.sqrt(magic);
+        dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
+        dLng = (dLng * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
+        double mgLat = lat + dLat;
+        double mgLng = lng + dLng;
+        return new Gps(mgLat, mgLng);
+    }
+
+    /***
+     * wgs84到gcj02转换
+     * @param lat
+     * @param lng
+     * @return
+     */
+    public static Gps wgs84_To_Gcj02(double lat, double lng) {
+        return transform(lat, lng);
+    }
+
+    /***
+     * 简单的gcj02到wgs84坐标类型转换,只做了一次迭代
+     */
+    public static Gps gcj02_To_Wgs84(double lat, double lng) {
+        Gps gps = transform(lat, lng);
+        double lngtitude = lng * 2 - gps.lng;
+        double latitude = lat * 2 - gps.lat;
+        return new Gps(latitude, lngtitude);
+    }
+
+    /***
+     * 稍微精确一点的gcj02到wgs84转换
+     * @param lat
+     * @param lng
+     * @return
+     */
+    public static Gps gcj02_To_Wgs84_exact(double lat,double lng) {
+        if (outOfChina(lat, lng)) {
+            return gcj02_To_Wgs84(lat, lng);
+        }
+        double initDelta = 0.01;
+        double threshold = 0.000001;
+        double dLat = initDelta;
+        double dLng = initDelta;
+        double mLat = lat - dLat;
+        double mLng = lng - dLng;
+        double pLat = lat + dLat;
+        double pLng = lng + dLng;
+        double wgsLat = 0;
+        double wgsLng = 0;
+        int i = 0;
+        while (true) {
+            wgsLat = (mLat + pLat) / 2;
+            wgsLng = (mLng + pLng) / 2;
+            Gps tmp = wgs84_To_Gcj02(wgsLat, wgsLng);
+            dLat = tmp.lat - lat;
+            dLng = tmp.lng - lng;
+            if ((Math.abs(dLat) < threshold) && (Math.abs(dLng) < threshold)) {
+                break;
+            }
+            if (dLat > 0) { pLat = wgsLat; } else { mLat = wgsLat;}
+            if (dLng > 0) { pLng = wgsLng; } else { mLng = wgsLng;}
+
+            if (++i > 1000) break;
+        }
+
+        return new Gps(wgsLat, wgsLng);
+    }
+
+    /***
+     * 百度坐标是在火星坐标基础上做的二次加密
+     * @param gg_lat
+     * @param gg_lng
+     * @return
+     */
+    public static Gps gcj02_To_Bd09(double gg_lat, double gg_lng) {
+        double x = gg_lng, y = gg_lat;
+        double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * pi);
+        double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * pi);
+        double bd_lng = z * Math.cos(theta) + 0.0065;
+        double bd_lat = z * Math.sin(theta) + 0.006;
+        return new Gps(bd_lat, bd_lng);
+    }
+
+    /***
+     * 百度坐标与火星坐标逆向转换
+     * @param bd_lat
+     * @param bd_lng
+     * @return
+     */
+    public static Gps bd09_To_Gcj02(double bd_lat, double bd_lng) {
+        double x = bd_lng - 0.0065, y = bd_lat - 0.006;
+        double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * pi);
+        double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * pi);
+        double gg_lng = z * Math.cos(theta);
+        double gg_lat = z * Math.sin(theta);
+        return new Gps(gg_lat, gg_lng);
+    }
+
+    public static void main(String[] args) {
+        Gps gps1 = new Gps(39.9072885060602, 116.39123343289631);
+        Gps gps = new Gps(33.41499708333333, 102.34823608333333);
+
+        System.out.println(gps);//{39.9072885060602,116.39123343289631}
+        Gps gps2 = wgs84_To_Gcj02(gps.lat, gps.lng);
+        System.out.println(gps2);//{39.9086897410389,116.39747455259267}
+        Gps gps3 = gcj02_To_Wgs84(gps2.lat, gps2.lng);
+        System.out.println(gps3);//{39.907286247736586,116.39123098626051}
+        Gps gps4 = gcj02_To_Wgs84_exact(gps2.lat, gps2.lng);
+        System.out.println(gps4);//{39.907288984202964,116.3912337078661} 相对一次迭代是精确了,但是好像也不是完全还原
+    }
+}

+ 43 - 0
content/content-service/src/main/resources/mapper/geo/BusStationMapper.xml

@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="cn.reghao.tnb.content.app.geo.db.mapper.BusStationMapper">
+    <insert id="save" useGeneratedKeys="true" keyProperty="id">
+        insert into geo_bus_station
+        (`lng`,`lat`,`station_name`,`pm`,`tid`,`line_name`)
+        values
+        (#{lng},#{lat},#{stationName},#{pm},#{tid},#{lineName})
+    </insert>
+    <insert id="saveAll" useGeneratedKeys="true" keyProperty="id">
+        insert into geo_bus_station
+        (`lng`,`lat`,`station_name`,`pm`,`tid`,`line_name`)
+        values
+        <foreach collection="list" item="item" index="index" separator=",">
+            (#{item.lng},#{item.lat},#{item.stationName},#{item.pm},#{item.tid},#{item.lineName})
+        </foreach>
+    </insert>
+
+    <select id="findAll" resultType="cn.reghao.tnb.content.app.geo.model.po.BusStation">
+        select *
+        from geo_bus_station
+        where type=2
+    </select>
+    <select id="findByLineName" resultType="cn.reghao.tnb.content.app.geo.model.vo.PublicBus">
+        select line_name,pm as pos,station_name
+        from geo_bus_station
+        where type=2 and line_name=#{lineName}
+        order by pm asc
+    </select>
+    <select id="findByStationName" resultType="cn.reghao.tnb.content.app.geo.model.po.BusStation">
+        select *
+        from geo_bus_station
+        where type=2 and station_name=#{stationName}
+    </select>
+    <select id="findByGroupLineName" resultType="java.lang.String">
+        select line_name
+        from geo_bus_station
+        where type=2
+        group by line_name
+        order by line_name asc
+    </select>
+</mapper>

+ 79 - 0
content/content-service/src/main/resources/mapper/geo/CameraPhotoMapper.xml

@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="cn.reghao.tnb.content.app.geo.db.mapper.CameraPhotoMapper">
+    <insert id="save" useGeneratedKeys="true" keyProperty="id">
+        insert into geo_camera_photo
+        (`album_id`,`object_id`,`channel_id`,`photo_url`,`manufacturer`,`model`,`software`,`shot_at`,`geo`)
+        values 
+        (#{albumId},#{objectId},#{channelId},#{photoUrl},#{manufacturer},#{model},#{software},#{shotAt},point(#{longitude},#{latitude}))
+    </insert>
+    <insert id="saveAll" useGeneratedKeys="true" keyProperty="id">
+        insert ignore into geo_camera_photo
+        (`album_id`,`object_id`,`channel_id`,`photo_url`,`manufacturer`,`model`,`software`,`shot_at`,`geo`)
+        values
+        <foreach collection="list" item="item" index="index" separator=",">
+            (#{item.albumId},#{item.objectId},#{item.channelId},#{item.photoUrl},#{item.manufacturer},#{item.model},#{item.software},#{item.shotAt},point(#{item.longitude},#{item.latitude}))
+        </foreach>
+    </insert>
+
+    <update id="updateSetAlbumId">
+        update geo_camera_photo
+        set album_id=#{albumId}
+        where object_id=#{objectId}
+    </update>
+
+    <delete id="delete">
+        delete from geo_camera_photo
+        where id=#{id}
+    </delete>
+
+    <resultMap id="mapMarker" type="cn.reghao.tnb.content.app.geo.model.vo.MapMarker">
+        <result property="id" column="id"/>
+        <result property="title" column="title"/>
+        <association property="position" javaType="cn.reghao.tnb.content.app.geo.model.vo.MapPoint">
+            <result property="lng" column="lng"/>
+            <result property="lat" column="lat"/>
+        </association>
+    </resultMap>
+    <select id="findByGeoGroup" resultMap="mapMarker">
+        select object_id as id, manufacturer as title,x(geo) as lng,y(geo) as lat
+        from geo_camera_photo
+        where album_id=0
+        group by geo
+        order by shot_at desc
+        limit #{pageSize}
+    </select>
+    <select id="findByWestGeoGroup" resultMap="mapMarker">
+        select object_id as id, manufacturer as title,x(geo) as lng,y(geo) as lat
+        from geo_camera_photo
+        where album_id=0
+        group by geo
+        order by shot_at desc
+        limit #{pageSize}
+    </select>
+    <select id="findByAlbumId" resultMap="mapMarker">
+        select object_id as id, manufacturer as title,x(geo) as lng,y(geo) as lat
+        from geo_camera_photo
+        where album_id!=0
+        group by geo
+        order by shot_at desc
+        limit #{pageSize}
+    </select>
+
+    <select id="findMarkerInfoById" resultType="cn.reghao.tnb.content.app.geo.model.vo.MarkerInfo">
+        select object_id as upload_id,channel_id,photo_url,
+        manufacturer as item_id, model as sku, date_format(shot_at,'%Y-%m-%d %H:%i:%s') as replyContent
+        from geo_camera_photo
+        where object_id=#{id}
+    </select>
+    <select id="findByObjectId" resultType="cn.reghao.tnb.content.app.geo.model.po.CameraPhoto">
+        select *
+        from geo_camera_photo
+        where object_id=#{objectId}
+    </select>
+    <select id="findAll" resultType="cn.reghao.tnb.content.app.geo.model.po.CameraPhoto">
+        select *
+        from geo_camera_photo
+    </select>
+</mapper>

+ 17 - 0
content/content-service/src/main/resources/mapper/geo/GeoEarthMapper.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="cn.reghao.tnb.content.app.geo.db.mapper.GeoEarthMapper">
+    <insert id="save" useGeneratedKeys="true" keyProperty="id">
+        insert into geo_earth
+        (`name`,`template`)
+        values 
+        (#{name},#{template})
+    </insert>
+    
+    <select id="findByName" resultType="cn.reghao.tnb.content.app.geo.model.po.GeoEarth">
+        select *
+        from geo_earth
+        where `name`=#{name}
+    </select>
+</mapper>

+ 16 - 0
content/content-service/src/main/resources/mapper/geo/GeoItemMapper.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="cn.reghao.tnb.content.app.geo.db.mapper.GeoItemMapper">
+    <insert id="save" useGeneratedKeys="true" keyProperty="id">
+        insert into geo_item
+        (`name`,`total`)
+        values 
+        (#{name},#{total})
+    </insert>
+    
+    <select id="findAll" resultType="cn.reghao.tnb.content.app.geo.model.po.GeoItem">
+        select *
+        from geo_item
+    </select>
+</mapper>

+ 35 - 0
content/content-service/src/main/resources/mapper/geo/GeoPointMapper.xml

@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="cn.reghao.tnb.content.app.geo.db.mapper.GeoPointMapper">
+    <insert id="save" useGeneratedKeys="true" keyProperty="id">
+        insert into geo_point
+        (`geo`,`create_by`)
+        values 
+        (point(#{longitude},#{latitude}), #{createBy})
+    </insert>
+    <insert id="saveAll" useGeneratedKeys="true" keyProperty="id">
+        insert ignore into geo_point
+        (`geo`,`create_by`)
+        values
+        <foreach collection="list" item="item" index="index" separator=",">
+            (point(#{item.longitude},#{item.latitude}), #{item.createBy})
+        </foreach>
+    </insert>
+
+    <resultMap id="photoGeo" type="cn.reghao.tnb.content.app.geo.model.po.MallReplyPhoto">
+        <result property="id" column="id"/>
+        <result property="replyId" column="reply_id"/>
+        <result property="photoUrl" column="photo_url"/>
+        <association property="geoPoint" javaType="cn.reghao.tnb.content.app.geo.model.vo.MapPoint">
+            <result property="lng" column="lng"/>
+            <result property="lat" column="lat"/>
+        </association>
+    </resultMap>
+    <select id="findAll" resultType="cn.reghao.tnb.content.app.geo.model.po.GeoPoint">
+        select id,create_time,x(geo) as longitude,y(geo) as latitude,create_by
+        from geo_point
+        order by id asc
+        limit 20
+    </select>
+</mapper>

+ 25 - 0
content/content-service/src/main/resources/mapper/geo/GeoPolygonMapper.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="cn.reghao.tnb.content.app.geo.db.mapper.GeoPolygonMapper">
+    <insert id="save" useGeneratedKeys="true" keyProperty="id">
+        insert into geo_polygon
+        (`id`,`pid`,`deep`,`name`,`ext_name`,`geo`,`polygon`)
+        values
+        (#{id},#{pid},#{deep},#{name},#{extName},point(#{longitude},#{latitude}),GeomFromText('POLYGON((${polygon}))'))
+    </insert>
+    <insert id="saveAll" useGeneratedKeys="true" keyProperty="id">
+        insert ignore into geo_polygon
+        (`id`,`pid`,`deep`,`name`,`ext_name`,`geo`,`polygon`)
+        values
+        <foreach collection="list" item="item" index="index" separator=",">
+        (#{item.id},#{item.pid},#{item.deep},#{item.name},#{item.extName},point(#{item.longitude},#{item.latitude}),GeomFromText('POLYGON((${item.polygon}))'))
+        </foreach>
+    </insert>
+
+    <select id="findByPoint" resultType="java.lang.Integer">
+        select id
+        from geo_polygon
+        where st_within(point(#{lng},#{lat}), polygon);
+    </select>
+</mapper>

+ 30 - 0
content/content-service/src/main/resources/mapper/geo/GeoScopeMapper.xml

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="cn.reghao.tnb.content.app.geo.db.mapper.GeoScopeMapper">
+    <insert id="save" useGeneratedKeys="true" keyProperty="id">
+        insert into geo_scope
+        (`id`,`pid`,`name`,`lng_east`,`lng_west`,`lat_north`,`lat_south`)
+        values 
+        (#{id},#{pid},#{name},#{lngEast},#{lngWest},#{latNorth},#{latSouth})
+    </insert>
+    <insert id="saveAll" useGeneratedKeys="true" keyProperty="id">
+        insert ignore into geo_scope
+        (`id`,`pid`,`name`,`lng_east`,`lng_west`,`lat_north`,`lat_south`)
+        values
+        <foreach collection="list" item="item" index="index" separator=",">
+            (#{item.id},#{item.pid},#{item.name},#{item.lngEast},#{item.lngWest},#{item.latNorth},#{item.latSouth})
+        </foreach>
+    </insert>
+
+    <select id="findById" resultType="cn.reghao.tnb.content.app.geo.model.po.GeoScope">
+        select *
+        from geo_scope
+        where `id`=#{id}
+    </select>
+    <select id="findByName" resultType="cn.reghao.tnb.content.app.geo.model.po.GeoScope">
+        select *
+        from geo_scope
+        where `name` like concat('%',#{name},'%')
+    </select>
+</mapper>

+ 55 - 0
content/content-service/src/main/resources/mapper/geo/JobLocationMapper.xml

@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="cn.reghao.tnb.content.app.geo.db.mapper.JobLocationMapper">
+    <insert id="save" useGeneratedKeys="true" keyProperty="id">
+        insert into geo_job_location
+        (`company_name`,`issue_date`,`job_href`,`job_describe`,`salary_min`,`salary_max`,`salary_str`,`geo`)
+        values
+        (#{companyName},#{issueDate},#{jobHref},#{jobDescribe},#{salaryMin},#{salaryMax},#{salaryStr},point(#{longitude},#{latitude}))
+    </insert>
+    <insert id="saveAll" useGeneratedKeys="true" keyProperty="id">
+        insert ignore into geo_job_location
+        (`company_name`,`issue_date`,`job_href`,`job_describe`,`salary_min`,`salary_max`,`salary_str`,`geo`)
+        values
+        <foreach collection="list" item="item" index="index" separator=",">
+            (#{item.companyName},#{item.issueDate},#{item.jobHref},#{item.jobDescribe},#{item.salaryMin},#{item.salaryMax},#{item.salaryStr},point(#{item.longitude},#{item.latitude}))
+        </foreach>
+    </insert>
+
+    <resultMap id="photoGeo" type="cn.reghao.tnb.content.app.geo.model.po.MallReplyPhoto">
+        <result property="id" column="id"/>
+        <result property="replyId" column="reply_id"/>
+        <result property="photoUrl" column="photo_url"/>
+        <association property="geoPoint" javaType="cn.reghao.tnb.content.app.geo.model.vo.MapPoint">
+            <result property="lng" column="lng"/>
+            <result property="lat" column="lat"/>
+        </association>
+    </resultMap>
+    <select id="findAll" resultMap="photoGeo">
+        select id,reply_id,photo_url,x(geo) as lng,y(geo) as lat
+        from geo_job_location
+    </select>
+    <select id="findMarkerInfoById" resultType="cn.reghao.tnb.content.app.geo.model.vo.MarkerInfo">
+        select reply.item_id,reply.reply_id,reply.extra as sku,reply.reply_content,reply.append_content,
+        photo.upload_id,photo.channel_id,photo.photo_url
+        from geo_job_location photo
+        inner join geo_mall_reply reply
+        on photo.reply_id=reply.reply_id and photo.id=#{id}
+    </select>
+
+    <resultMap id="mapMarker" type="cn.reghao.tnb.content.app.geo.model.vo.MapMarker">
+        <result property="id" column="id"/>
+        <result property="title" column="company_name"/>
+        <association property="position" javaType="cn.reghao.tnb.content.app.geo.model.vo.MapPoint">
+            <result property="lng" column="lng"/>
+            <result property="lat" column="lat"/>
+        </association>
+    </resultMap>
+    <select id="findMapMarker" resultMap="mapMarker">
+        select id,company_name,x(geo) as lng,y(geo) as lat
+        from geo_job_location photo
+        order by issue_date desc
+        limit 1000
+    </select>
+</mapper>

+ 34 - 0
content/content-service/src/main/resources/mapper/geo/MallReplyMapper.xml

@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="cn.reghao.tnb.content.app.geo.db.mapper.MallReplyMapper">
+    <insert id="save" useGeneratedKeys="true" keyProperty="id">
+        insert into geo_mall_reply
+        (`id`,`deleted`,`create_time`,`update_time`,`item_type`,`item_id`,`reply_id`,`reply_content`,`append_content`,`extra`,`username`,`avatar_url`)
+        values 
+        (#{id},#{deleted},#{createTime},#{updateTime},#{itemType},#{itemId},#{replyId},#{replyContent},#{appendContent},#{extra},#{username},#{avatarUrl})
+    </insert>
+
+    <select id="findAll" resultType="cn.reghao.tnb.content.app.geo.model.po.MallReply">
+        select *
+        from geo_mall_reply
+        limit 1000
+    </select>
+    <select id="findByItemType" resultType="cn.reghao.tnb.content.app.geo.model.po.MallReply">
+        select *
+        from geo_mall_reply
+        where item_type=#{itemType}
+        order by id asc
+        limit 500
+    </select>
+    <select id="findByReplyId" resultType="cn.reghao.tnb.content.app.geo.model.po.MallReply">
+        select *
+        from geo_mall_reply
+        where reply_id=#{reply_id}
+    </select>
+    <select id="findByItemId" resultType="cn.reghao.tnb.content.app.geo.model.po.MallReply">
+        select *
+        from geo_mall_reply
+        where item_id=#{itemId}
+    </select>
+</mapper>

+ 91 - 0
content/content-service/src/main/resources/mapper/geo/MallReplyPhotoMapper.xml

@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="cn.reghao.tnb.content.app.geo.db.mapper.MallReplyPhotoMapper">
+    <insert id="save" useGeneratedKeys="true" keyProperty="id">
+        insert into geo_mall_reply_photo
+        (`reply_id`,`upload_id`,`channel_id`,`photo_url`,`manufacturer`,`model`,`software`,`shot_at`,`geo`)
+        values
+        (#{replyId},#{uploadId},#{channelId},#{photoUrl},#{manufacturer},#{model},#{software},#{shotAt},point(#{longitude},#{latitude}))
+    </insert>
+    <insert id="saveAll" useGeneratedKeys="true" keyProperty="id">
+        insert ignore into geo_mall_reply_photo
+        (`reply_id`,`upload_id`,`channel_id`,`photo_url`,`manufacturer`,`model`,`software`,`shot_at`,`geo`)
+        values
+        <foreach collection="list" item="item" index="index" separator=",">
+            (#{item.replyId},#{item.uploadId},#{item.channelId},#{item.photoUrl},#{item.manufacturer},#{item.model},#{item.software},#{item.shotAt},point(#{item.longitude},#{item.latitude}))
+        </foreach>
+    </insert>
+
+    <resultMap id="photoGeo" type="cn.reghao.tnb.content.app.geo.model.po.MallReplyPhoto">
+        <result property="id" column="id"/>
+        <result property="replyId" column="reply_id"/>
+        <result property="photoUrl" column="photo_url"/>
+        <association property="geoPoint" javaType="cn.reghao.tnb.content.app.geo.model.vo.MapPoint">
+            <result property="lng" column="lng"/>
+            <result property="lat" column="lat"/>
+        </association>
+    </resultMap>
+    <select id="findAll" resultMap="photoGeo">
+        select id,reply_id,photo_url,x(geo) as lng,y(geo) as lat
+        from geo_mall_reply_photo
+    </select>
+    <select id="findMarkerInfoById" resultType="cn.reghao.tnb.content.app.geo.model.vo.MarkerInfo">
+        select reply.item_id,reply.reply_id,reply.extra as sku,reply.reply_content,reply.append_content,
+        photo.upload_id,photo.channel_id,photo.photo_url
+        from geo_mall_reply_photo photo
+        inner join geo_mall_reply reply
+        on photo.reply_id=reply.reply_id and photo.id=#{id}
+    </select>
+
+    <resultMap id="mapMarker" type="cn.reghao.tnb.content.app.geo.model.vo.MapMarker">
+        <result property="id" column="id"/>
+        <result property="title" column="extra"/>
+        <association property="position" javaType="cn.reghao.tnb.content.app.geo.model.vo.MapPoint">
+            <result property="lng" column="lng"/>
+            <result property="lat" column="lat"/>
+        </association>
+    </resultMap>
+    <select id="findAllByReplyIdGroup" resultMap="mapMarker">
+        select photo.id,photo.manufacturer as extra,photo.photo_url,x(photo.geo) as lng,y(photo.geo) as lat
+        from geo_mall_reply_photo photo
+        inner join geo_mall_reply reply
+        on photo.reply_id=reply.reply_id
+        group by photo.reply_id
+        order by photo.id desc
+        limit #{pageSize}
+    </select>
+    <select id="findByReplyIdGroup" resultMap="mapMarker">
+        select photo.id,photo.manufacturer as extra,photo.photo_url,x(photo.geo) as lng,y(photo.geo) as lat
+        from geo_mall_reply_photo photo
+        inner join geo_mall_reply reply
+        on photo.reply_id=reply.reply_id and x(photo.geo)>0.0000 and reply.item_type=#{itemType}
+        group by photo.reply_id
+        order by photo.id desc
+        limit #{pageSize}
+    </select>
+    <!-- 根据中国东西南北位置返回 -->
+    <select id="findByGeoScope" resultMap="mapMarker">
+        select photo.id,reply.username as extra,photo.photo_url,x(photo.geo) as lng,y(photo.geo) as lat
+        from geo_mall_reply_photo photo
+        inner join geo_mall_reply reply
+        on photo.reply_id=reply.reply_id
+        and x(photo.geo)>#{geoScope.lngStart} and x(photo.geo)&lt;#{geoScope.lngEnd}
+        and y(photo.geo)>#{geoScope.latStart} and y(photo.geo)&lt;#{geoScope.latEnd}
+        and reply.item_type=#{itemType}
+        group by photo.reply_id
+        order by x(photo.geo) desc
+        limit #{pageSize}
+    </select>
+    <!-- 由西向东升序 -->
+    <select id="findByWestChina" resultMap="mapMarker">
+        select photo.id,reply.extra,photo.photo_url,x(photo.geo) as lng,y(photo.geo) as lat
+        from geo_mall_reply_photo photo
+        inner join geo_mall_reply reply
+        on photo.reply_id=reply.reply_id
+        and reply.item_type=#{itemType}
+        group by photo.reply_id
+        order by photo.id desc
+        limit #{pageSize}
+    </select>
+</mapper>