Переглянути джерело

创建围栏的增删改查功能

Simon 1 рік тому
батько
коміт
408837b4c2
34 змінених файлів з 3692 додано та 5 видалено
  1. 133 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/TElectronicFenceController.java
  2. 98 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/TElectronicFenceKeyController.java
  3. 104 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/TElectronicFenceServiceController.java
  4. 7 0
      ruoyi-admin/src/main/resources/application.properties
  5. 3 2
      ruoyi-admin/src/main/resources/application.yml
  6. 69 0
      ruoyi-common/src/main/java/com/ruoyi/common/constant/AMapConstants.java
  7. 254 3
      ruoyi-common/src/main/java/com/ruoyi/common/constant/HttpStatus.java
  8. 49 0
      ruoyi-common/src/main/java/com/ruoyi/common/core/domain/AMapResult.java
  9. 11 0
      ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java
  10. 208 0
      ruoyi-system/src/main/java/com/ruoyi/system/domain/TElectronicFence.java
  11. 81 0
      ruoyi-system/src/main/java/com/ruoyi/system/domain/TElectronicFenceKey.java
  12. 95 0
      ruoyi-system/src/main/java/com/ruoyi/system/domain/TElectronicFenceService.java
  13. 22 0
      ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/AMapGeoFenceDto.java
  14. 48 0
      ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/AMapTrackDto.java
  15. 45 0
      ruoyi-system/src/main/java/com/ruoyi/system/domain/enums/ElectronicFenceEnum.java
  16. 95 0
      ruoyi-system/src/main/java/com/ruoyi/system/domain/to/AMapBaseTo.java
  17. 52 0
      ruoyi-system/src/main/java/com/ruoyi/system/domain/to/AMapUpdateCircleTo.java
  18. 36 0
      ruoyi-system/src/main/java/com/ruoyi/system/domain/to/AMapUpdateDistrictTo.java
  19. 52 0
      ruoyi-system/src/main/java/com/ruoyi/system/domain/to/AMapUpdatePolyLineTo.java
  20. 37 0
      ruoyi-system/src/main/java/com/ruoyi/system/domain/to/AMapUpdatePolygonTo.java
  21. 277 0
      ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/ElectronicFenceVo.java
  22. 63 0
      ruoyi-system/src/main/java/com/ruoyi/system/mapper/TElectronicFenceKeyMapper.java
  23. 81 0
      ruoyi-system/src/main/java/com/ruoyi/system/mapper/TElectronicFenceMapper.java
  24. 63 0
      ruoyi-system/src/main/java/com/ruoyi/system/mapper/TElectronicFenceServiceMapper.java
  25. 75 0
      ruoyi-system/src/main/java/com/ruoyi/system/service/ITElectronicFenceKeyService.java
  26. 81 0
      ruoyi-system/src/main/java/com/ruoyi/system/service/ITElectronicFenceService.java
  27. 77 0
      ruoyi-system/src/main/java/com/ruoyi/system/service/ITElectronicFenceServiceService.java
  28. 112 0
      ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TElectronicFenceKeyServiceImpl.java
  29. 815 0
      ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TElectronicFenceServiceImpl.java
  30. 116 0
      ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TElectronicFenceServiceServiceImpl.java
  31. 107 0
      ruoyi-system/src/main/java/com/ruoyi/system/timing/GeofenceDeleteTiming.java
  32. 82 0
      ruoyi-system/src/main/resources/mapper/system/TElectronicFenceKeyMapper.xml
  33. 155 0
      ruoyi-system/src/main/resources/mapper/system/TElectronicFenceMapper.xml
  34. 89 0
      ruoyi-system/src/main/resources/mapper/system/TElectronicFenceServiceMapper.xml

+ 133 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/TElectronicFenceController.java

@@ -0,0 +1,133 @@
+package com.ruoyi.web.controller.system;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+
+import com.ruoyi.system.domain.vo.ElectronicFenceVo;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.system.domain.TElectronicFence;
+import com.ruoyi.system.service.ITElectronicFenceService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 【请填写功能名称】Controller
+ *
+ * @author ruoyi
+ * @date 2023-09-14
+ */
+@RestController
+@RequestMapping("/system/electronic/fence")
+public class TElectronicFenceController extends BaseController {
+    @Autowired
+    private ITElectronicFenceService tElectronicFenceService;
+
+    /**
+     * 查询【请填写功能名称】列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:fence:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(TElectronicFence tElectronicFence) {
+        startPage();
+        List<TElectronicFence> list = tElectronicFenceService.selectTElectronicFenceList(tElectronicFence);
+        return getDataTable(list);
+    }
+
+
+    /**
+     * 查询【请填写功能名称】列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:fence:list')")
+    @GetMapping("/list/device/{deviceId}")
+    public TableDataInfo list(@PathVariable("deviceId") Long deviceId) {
+        startPage();
+        List<TElectronicFence> list = tElectronicFenceService.selectTElectronicFenceListByDeviceId(deviceId);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出【请填写功能名称】列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:fence:export')")
+    @Log(title = "【请填写功能名称】", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, TElectronicFence tElectronicFence) {
+        List<TElectronicFence> list = tElectronicFenceService.selectTElectronicFenceList(tElectronicFence);
+        ExcelUtil<TElectronicFence> util = new ExcelUtil<TElectronicFence>(TElectronicFence.class);
+        util.exportExcel(response, list, "【请填写功能名称】数据");
+    }
+
+    /**
+     * 获取【请填写功能名称】详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('system:fence:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id) {
+        return success(tElectronicFenceService.selectTElectronicFenceById(id));
+    }
+
+//    /**
+//     * 新增【请填写功能名称】
+//     */
+//    @PreAuthorize("@ss.hasPermi('system:fence:add')")
+//    @Log(title = "【请填写功能名称】", businessType = BusinessType.INSERT)
+//    @PostMapping
+//    public AjaxResult add(@RequestBody TElectronicFence tElectronicFence) {
+//        return toAjax(tElectronicFenceService.insertTElectronicFence(tElectronicFence));
+//    }
+
+    /**
+     * 新增【请填写功能名称】
+     */
+    @PreAuthorize("@ss.hasPermi('system:fence:add')")
+    @Log(title = "【请填写功能名称】", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody @Validated ElectronicFenceVo electronicFenceVo) {
+        electronicFenceVo.setUsdId(getUserId());
+        return toAjax(tElectronicFenceService.insertTElectronicFenceVo(electronicFenceVo));
+    }
+
+//    /**
+//     * 修改【请填写功能名称】
+//     */
+//    @PreAuthorize("@ss.hasPermi('system:fence:edit')")
+//    @Log(title = "【请填写功能名称】", businessType = BusinessType.UPDATE)
+//    @PutMapping
+//    public AjaxResult edit(@RequestBody TElectronicFence tElectronicFence) {
+//        return toAjax(tElectronicFenceService.updateTElectronicFence(tElectronicFence));
+//    }
+
+    /**
+     * 修改【请填写功能名称】
+     */
+    @PreAuthorize("@ss.hasPermi('system:fence:edit')")
+    @Log(title = "【请填写功能名称】", businessType = BusinessType.UPDATE)
+    @PutMapping("/edit")
+    public AjaxResult edit(@RequestBody ElectronicFenceVo tElectronicFenceEditVo) {
+        return toAjax(tElectronicFenceService.updateTElectronicFenceEditVo(tElectronicFenceEditVo));
+    }
+
+    /**
+     * 删除【请填写功能名称】
+     */
+    @PreAuthorize("@ss.hasPermi('system:fence:remove')")
+    @Log(title = "【请填写功能名称】", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids) {
+        return toAjax(tElectronicFenceService.deleteTElectronicFenceByIds(ids));
+    }
+}

+ 98 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/TElectronicFenceKeyController.java

@@ -0,0 +1,98 @@
+package com.ruoyi.web.controller.system;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.system.domain.TElectronicFenceKey;
+import com.ruoyi.system.service.ITElectronicFenceKeyService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 【请填写功能名称】Controller
+ *
+ * @author ruoyi
+ * @date 2023-09-14
+ */
+@RestController
+@RequestMapping("/system/electronic/fence/key")
+public class TElectronicFenceKeyController extends BaseController {
+    @Autowired
+    private ITElectronicFenceKeyService tElectronicFenceKeyService;
+
+    /**
+     * 查询【请填写功能名称】列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:key:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(TElectronicFenceKey tElectronicFenceKey) {
+        startPage();
+        List<TElectronicFenceKey> list = tElectronicFenceKeyService.selectTElectronicFenceKeyList(tElectronicFenceKey);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出【请填写功能名称】列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:key:export')")
+    @Log(title = "【请填写功能名称】", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, TElectronicFenceKey tElectronicFenceKey) {
+        List<TElectronicFenceKey> list = tElectronicFenceKeyService.selectTElectronicFenceKeyList(tElectronicFenceKey);
+        ExcelUtil<TElectronicFenceKey> util = new ExcelUtil<TElectronicFenceKey>(TElectronicFenceKey.class);
+        util.exportExcel(response, list, "【请填写功能名称】数据");
+    }
+
+    /**
+     * 获取【请填写功能名称】详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('system:key:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id) {
+        return success(tElectronicFenceKeyService.selectTElectronicFenceKeyById(id));
+    }
+
+    /**
+     * 新增【请填写功能名称】
+     */
+    @PreAuthorize("@ss.hasPermi('system:key:add')")
+    @Log(title = "【请填写功能名称】", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody TElectronicFenceKey tElectronicFenceKey) {
+        return toAjax(tElectronicFenceKeyService.insertTElectronicFenceKey(tElectronicFenceKey));
+    }
+
+    /**
+     * 修改【请填写功能名称】
+     */
+    @PreAuthorize("@ss.hasPermi('system:key:edit')")
+    @Log(title = "【请填写功能名称】", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody TElectronicFenceKey tElectronicFenceKey) {
+        return toAjax(tElectronicFenceKeyService.updateTElectronicFenceKey(tElectronicFenceKey));
+    }
+
+    /**
+     * 删除【请填写功能名称】
+     */
+    @PreAuthorize("@ss.hasPermi('system:key:remove')")
+    @Log(title = "【请填写功能名称】", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids) {
+        return toAjax(tElectronicFenceKeyService.deleteTElectronicFenceKeyByIds(ids));
+    }
+}

+ 104 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/TElectronicFenceServiceController.java

@@ -0,0 +1,104 @@
+package com.ruoyi.web.controller.system;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.system.domain.TElectronicFenceService;
+import com.ruoyi.system.service.ITElectronicFenceServiceService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 【请填写功能名称】Controller
+ * 
+ * @author ruoyi
+ * @date 2023-09-14
+ */
+@RestController
+@RequestMapping("/system/electronic/fence/service")
+public class TElectronicFenceServiceController extends BaseController
+{
+    @Autowired
+    private ITElectronicFenceServiceService tElectronicFenceServiceService;
+
+    /**
+     * 查询【请填写功能名称】列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:service:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(TElectronicFenceService tElectronicFenceService)
+    {
+        startPage();
+        List<TElectronicFenceService> list = tElectronicFenceServiceService.selectTElectronicFenceServiceList(tElectronicFenceService);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出【请填写功能名称】列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:service:export')")
+    @Log(title = "【请填写功能名称】", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, TElectronicFenceService tElectronicFenceService)
+    {
+        List<TElectronicFenceService> list = tElectronicFenceServiceService.selectTElectronicFenceServiceList(tElectronicFenceService);
+        ExcelUtil<TElectronicFenceService> util = new ExcelUtil<TElectronicFenceService>(TElectronicFenceService.class);
+        util.exportExcel(response, list, "【请填写功能名称】数据");
+    }
+
+    /**
+     * 获取【请填写功能名称】详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('system:service:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(tElectronicFenceServiceService.selectTElectronicFenceServiceById(id));
+    }
+
+    /**
+     * 新增【请填写功能名称】
+     */
+    @PreAuthorize("@ss.hasPermi('system:service:add')")
+    @Log(title = "【请填写功能名称】", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody TElectronicFenceService tElectronicFenceService)
+    {
+        return toAjax(tElectronicFenceServiceService.insertTElectronicFenceService(tElectronicFenceService));
+    }
+
+    /**
+     * 修改【请填写功能名称】
+     */
+    @PreAuthorize("@ss.hasPermi('system:service:edit')")
+    @Log(title = "【请填写功能名称】", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody TElectronicFenceService tElectronicFenceService)
+    {
+        return toAjax(tElectronicFenceServiceService.updateTElectronicFenceService(tElectronicFenceService));
+    }
+
+    /**
+     * 删除【请填写功能名称】
+     */
+    @PreAuthorize("@ss.hasPermi('system:service:remove')")
+    @Log(title = "【请填写功能名称】", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(tElectronicFenceServiceService.deleteTElectronicFenceServiceByIds(ids));
+    }
+}

+ 7 - 0
ruoyi-admin/src/main/resources/application.properties

@@ -0,0 +1,7 @@
+# HttpClient 基本配置
+http.maxTotal=300
+http.defaultMaxPerRoute=50
+http.connectTimeout=1000
+http.connectionRequestTimeout=500
+http.socketTimeout=5000
+http.staleConnectionCheckEnabled=true

+ 3 - 2
ruoyi-admin/src/main/resources/application.yml

@@ -71,13 +71,14 @@ spring:
   # redis 配置
   redis:
     # 地址
-    host: localhost
+#    host: localhost
+    host: 192.168.56.10
     # 端口,默认为6379
     port: 6379
     # 数据库索引
     database: 0
     # 密码
-    password:
+    password: redis
 #    password: yyky@2023
     # 连接超时时间
     timeout: 10s

+ 69 - 0
ruoyi-common/src/main/java/com/ruoyi/common/constant/AMapConstants.java

@@ -0,0 +1,69 @@
+package com.ruoyi.common.constant;
+
+/**
+ * @ClassName: AMapConstants
+ * @Author: 于学智
+ * @Description: 高德服务Constants
+ * @CreateDate: 2023/9/13 23:04
+ * @Version: 1.0
+ * @E-mail:18722650553@139.com
+ * @Link:https://github.com/18722650553
+ */
+public class AMapConstants {
+
+    /**
+     * 创建服务(每个 Key 下最多注册15个 Service)
+     */
+    public static final String AMAP_TRACK_SERVICE_ADD = "https://tsapi.amap.com/v1/track/service/add";
+
+    /**
+     * 查询服务
+     */
+    public static final String AMAP_TRACK_SERVICE_LIST = "https://tsapi.amap.com/v1/track/service/list";
+
+    /**
+     * 删除围栏
+     */
+    public static final String AMAP_TRACK_SERVICE_DELETE = "https://tsapi.amap.com/v1/track/geofence/delete";
+
+    /**
+     * 创建圆形围栏
+     */
+    public static final String AMAP_GEOFENCE_ADD_CIRCLE = "https://tsapi.amap.com/v1/track/geofence/add/circle";
+
+    /**
+     * 更新圆形围栏
+     */
+    public static final String AMAP_GEOFENCE_UPDATE_CIRCLE = "https://tsapi.amap.com/v1/track/geofence/update/circle";
+
+    /**
+     * 创建多边形围栏
+     */
+    public static final String AMAP_GEOFENCE_ADD_POLYGON = "https://tsapi.amap.com/v1/track/geofence/add/polygon";
+
+    /**
+     * 更新多边形围栏
+     */
+    public static final String AMAP_GEOFENCE_UPDATE_POLYGON = "https://tsapi.amap.com/v1/track/geofence/update/polygon";
+
+    /**
+     * 创建线形围栏
+     */
+    public static final String AMAP_GEOFENCE_ADD_POLYLINE = "https://tsapi.amap.com/v1/track/geofence/add/polyline";
+
+    /**
+     * 更新线形围栏
+     */
+    public static final String AMAP_GEOFENCE_UPDATE_POLYLINE = "https://tsapi.amap.com/v1/track/geofence/update/polyline";
+
+    /**
+     * 创建行政区划围栏
+     */
+    public static final String AMAP_GEOFENCE_ADD_DISTRICT = "https://tsapi.amap.com/v1/track/geofence/add/district";
+
+    /**
+     * 更新行政区划围栏
+     */
+    public static final String AMAP_GEOFENCE_UPDATE_DISTRICT = "https://tsapi.amap.com/v1/track/geofence/update/district";
+
+}

+ 254 - 3
ruoyi-common/src/main/java/com/ruoyi/common/constant/HttpStatus.java

@@ -2,11 +2,10 @@ package com.ruoyi.common.constant;
 
 /**
  * 返回状态码
- * 
+ *
  * @author ruoyi
  */
-public class HttpStatus
-{
+public class HttpStatus {
     /**
      * 操作成功
      */
@@ -91,4 +90,256 @@ public class HttpStatus
      * 系统警告消息
      */
     public static final int WARN = 601;
+
+    //10000+ 为高德返回错误码
+
+    /**
+     * 高德-key不正确或过期
+     * (开发者发起请求时,传入的key不正确或者过期 )
+     */
+    public static final int AMAP_INVALID_USER_KEY = 10001;
+
+    /**
+     * 高德-没有权限使用相应的服务或者请求接口的路径拼写错误
+     * (1.开发者没有权限使用相应的服务,例如:开发者申请了WEB定位功能的key,却使用该key访问逆地理编码功能时,就会返回该错误。反之亦然。
+     * 2.开发者请求接口的路径拼写错误。例如:正确的https://restapi.amap.com/v3/ip在程序中被拼装写了https://restapi.amap.com/vv3/ip")
+     */
+    public static final int AMAP_SERVICE_NOT_AVAILABLE = 10002;
+
+    /**
+     * 高德-访问已超出日访问量
+     * (开发者的日访问量超限,被系统自动封停,第二天0:00会自动解封。)
+     */
+    public static final int AMAP_DAILY_QUERY_OVER_LIMIT = 10003;
+
+    /**
+     * 高德-单位时间内访问过于频繁
+     * (开发者的单位时间内(1分钟)访问量超限,被系统自动封停,下一分钟自动解封。)
+     */
+    public static final int AMAP_ACCESS_TOO_FREQUENT = 10004;
+
+    /**
+     * 高德-IP白名单出错,发送请求的服务器IP不在IP白名单内
+     * (开发者在LBS官网控制台设置的IP白名单不正确。白名单中未添加对应服务器的出口IP。可到"控制台>配置"  中设定IP白名单。)
+     */
+    public static final int AMAP_INVALID_USER_IP = 10005;
+
+    /**
+     * 高德-绑定域名无效
+     * (开发者绑定的域名无效,需要在官网控制台重新设置)
+     */
+    public static final int AMAP_INVALID_USER_DOMAIN = 10006;
+
+    /**
+     * 高德-数字签名未通过验证
+     * (开发者签名未通过开发者在key控制台中,开启了“数字签名”功能,但没有按照指定算法生成“数字签名”。)
+     */
+    public static final int AMAP_INVALID_USER_SIGNATURE = 10007;
+
+    /**
+     * 高德-MD5安全码未通过验证
+     * (需要开发者判定key绑定的SHA1,package是否与sdk包里的一致)
+     */
+    public static final int AMAP_INVALID_USER_SCODE = 10008;
+
+    /**
+     * 高德-请求key与绑定平台不符
+     * (请求中使用的key与绑定平台不符,例如:开发者申请的是js api的key,却用来调web服务接口)
+     */
+    public static final int AMAP_USERKEY_PLAT_NOMATCH = 10009;
+
+    /**
+     * 高德-IP访问超限
+     * (未设定IP白名单的开发者使用key发起请求,从单个IP向服务器发送的请求次数超出限制,被系统自动封停。封停后无法自动恢复,需要提交工单联系我们。)
+     */
+    public static final int AMAP_IP_QUERY_OVER_LIMIT = 10010;
+
+    /**
+     * 高德-服务不支持https请求
+     * (服务不支持https请求,如果需要申请支持,请提交工单联系我们)
+     */
+    public static final int AMAP_NOT_SUPPORT_HTTPS = 10011;
+
+    /**
+     * 高德-权限不足,服务请求被拒绝
+     * (由于不具备请求该服务的权限,所以服务被拒绝。)
+     */
+    public static final int AMAP_INSUFFICIENT_PRIVILEGES = 10012;
+
+    /**
+     * 高德-Key被删除
+     * (开发者删除了key,key被删除后无法正常使用)
+     */
+    public static final int AMAP_USER_KEY_RECYCLED = 10013;
+
+    /**
+     * 高德-云图服务QPS超限
+     * ( QPS超出限制,超出部分的请求被拒绝。限流阈值内的请求依旧会正常返回)
+     */
+    public static final int AMAP_QPS_HAS_EXCEEDED_THE_LIMIT = 10014;
+
+    /**
+     * 高德-受单机QPS限流限制
+     * ( 受单机QPS限流限制时出现该问题,建议降低请求的QPS或在控制台提工单联系我们)
+     */
+    public static final int AMAP_GATEWAY_TIMEOUT = 10015;
+
+    /**
+     * 高德-服务器负载过高
+     * (服务器负载过高,请稍后再试)
+     */
+    public static final int AMAP_SERVER_IS_BUSY = 10016;
+
+    /**
+     * 高德-所请求的资源不可用
+     * (所请求的资源不可用)
+     */
+    public static final int AMAP_RESOURCE_UNAVAILABLE = 10017;
+
+    /**
+     * 高德-使用的某个服务总QPS超限
+     * (QPS超出限制,超出部分的请求被拒绝。限流阈值内的请求依旧会正常返回)
+     */
+    public static final int AMAP_CQPS_HAS_EXCEEDED_THE_LIMIT = 10019;
+
+    /**
+     * 高德-某个Key使用某个服务接口QPS超出限制
+     * (QPS超出限制,超出部分的请求被拒绝。限流阈值内的请求依旧会正常返回)
+     */
+    public static final int AMAP_CKQPS_HAS_EXCEEDED_THE_LIMIT = 10020;
+
+    /**
+     * 高德-来自于同一IP的访问,使用某个服务QPS超出限制
+     * ( QPS超出限制,超出部分的请求被拒绝。限流阈值内的请求依旧会正常返回)
+     */
+    public static final int AMAP_CIQPS_HAS_EXCEEDED_THE_LIMIT = 10021;
+
+    /**
+     * 高德-某个Key,来自于同一IP的访问,使用某个服务QPS超出限制
+     * (QPS超出限制,超出部分的请求被拒绝。限流阈值内的请求依旧会正常返回)
+     */
+    public static final int AMAP_CIKQPS_HAS_EXCEEDED_THE_LIMIT = 10022;
+
+    /**
+     * 高德-某个KeyQPS超出限制
+     * (QPS超出限制,超出部分的请求被拒绝。限流阈值内的请求依旧会正常返回)
+     */
+    public static final int AMAP_KQPS_HAS_EXCEEDED_THE_LIMIT = 10023;
+
+    /**
+     * 高德-权限不足
+     * (数据的访问权限不足)
+     */
+    public static final int AMAP_INSUFFICIENT_PERMISSIONS = 10024;
+
+    /**
+     * 高德-请求参数非法
+     * ( 请求参数的值没有按照规范要求填写。例如,某参数值域范围为[1,3],开发者误填了’4’)
+     */
+    public static final int AMAP_INVALID_PARAMS = 20000;
+
+    /**
+     * 高德-缺少必填参数
+     * (缺少接口中要求的必填参数)
+     */
+    public static final int AMAP_MISSING_REQUIRED_PARAMS = 20001;
+
+    /**
+     * 高德-请求协议非法
+     * (比如某接口仅支持get请求,结果用了POST方式)
+     */
+    public static final int AMAP_ILLEGAL_REQUEST = 20002;
+
+    /**
+     * 高德-其他未知错误
+     * (其他未知错误,请通过工单反馈我们。)
+     */
+    public static final int AMAP_UNKNOWN_ERROR = 20003;
+
+    /**
+     * 高德-找不到ID
+     * (找不到相应的ID)
+     */
+    public static final int AMAP_ID_NOT_FOUND = 20004;
+
+    /**
+     * 高德-数据流错误
+     * (无法取得上传文件数据流)
+     */
+    public static final int AMAP_FILE_UPLOAD_FAILED = 20005;
+
+    /**
+     * 高德-协议错误
+     * (协议错误)
+     */
+    public static final int AMAP_INVALID_BINARY_PROTOCOL = 20006;
+
+    /**
+     * 高德-解密失败
+     * (解密失败)
+     */
+    public static final int AMAP_DECRYPTION_FAILED = 20007;
+
+    /**
+     * 高德-请求拒绝
+     * (请求拒绝)
+     */
+    public static final int AMAP_REQUEST_BREAKER = 20008;
+
+    /**
+     * 高德-参数已存在
+     * (填入的某些参数已经存在,请检查关键参数)
+     */
+    public static final int AMAP_EXISTING_ELEMENT = 20009;
+
+    /**
+     * 高德-参数不存在
+     * (填入的查找参数不存在,请检查对应参数是否存在)
+     */
+    public static final int AMAP_UNEXISTING_ELEMENT = 20010;
+
+    /**
+     * 高德-服务不存在
+     * (用户上传数据所绑定的服务不存在)
+     */
+    public static final int AMAP_SERVICE_NOT_FOUND = 20050;
+
+    /**
+     * 高德-设备不存在
+     * (用户上传数据所绑定的设备不存在)
+     */
+    public static final int AMAP_TERMINAL_NOT_FOUND = 20051;
+
+    /**
+     * 高德-部分点上传失败
+     * (部分点没有成功上传)
+     */
+    public static final int AMAP_PARTIAL_SUCCESS = 20100;
+
+    /**
+     * 高德-所有点上传失败
+     * (所有点都上传失败)
+     */
+    public static final int AMAP_NOTHING_SUCCESS = 20101;
+
+    /**
+     * 高德-设备个数过多
+     * (创建设备个数已超限)
+     */
+    public static final int AMAP_BEYOND_LIMIT = 20150;
+
+    /**
+     * 高德-服务响应失败
+     * (出现3开头的错误码,请先按照接口文档检查传入参数是否正确,若无法解决,请详细描述错误复现信息,请通过工单反馈我们。
+     * 如,30001、30002、30003、32000、32001、32002、32003、32200、32201、32202、32203。)
+     */
+    public static final int AMAP_ENGINE_RESPONSE_DATA_ERROR = 30000;
+
+    /**
+     * 高德-轨迹过长
+     * (轨迹长度超过5000公里,请检查传入的原始轨迹是否合理;)
+     */
+    public static final int AMAP_TOO_LONG_TRACK = 32005;
+
+
 }

+ 49 - 0
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/AMapResult.java

@@ -0,0 +1,49 @@
+package com.ruoyi.common.core.domain;
+
+/**
+ * @ClassName: AMapResult
+ * @Author: 于学智
+ * @Description: 高德地图API返回
+ * @CreateDate: 2023/9/13 22:16
+ * @Version: 1.0
+ * @E-mail:18722650553@139.com
+ * @Link:https://github.com/18722650553
+ */
+public class AMapResult<T> {
+    private int errcode;
+    private String errmsg;
+    private String errdetail;
+    private T data;
+
+    public int getErrcode() {
+        return errcode;
+    }
+
+    public void setErrcode(int errcode) {
+        this.errcode = errcode;
+    }
+
+    public String getErrmsg() {
+        return errmsg;
+    }
+
+    public void setErrmsg(String errmsg) {
+        this.errmsg = errmsg;
+    }
+
+    public String getErrdetail() {
+        return errdetail;
+    }
+
+    public void setErrdetail(String errdetail) {
+        this.errdetail = errdetail;
+    }
+
+    public T getData() {
+        return data;
+    }
+
+    public void setData(T data) {
+        this.data = data;
+    }
+}

+ 11 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java

@@ -11,6 +11,8 @@ import java.net.URL;
 import java.net.URLConnection;
 import java.nio.charset.StandardCharsets;
 import java.security.cert.X509Certificate;
+import java.util.HashMap;
+import java.util.Map;
 import javax.net.ssl.HostnameVerifier;
 import javax.net.ssl.HttpsURLConnection;
 import javax.net.ssl.SSLContext;
@@ -271,4 +273,13 @@ public class HttpUtils
             return true;
         }
     }
+
+    public static String getParamsToString(Map<Object, Object> params) {
+        StringBuilder stringBuilder = new StringBuilder();
+        for (Map.Entry<Object, Object> entry : params.entrySet()) {
+            stringBuilder.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
+        }
+        stringBuilder.deleteCharAt(stringBuilder.length() - 1);
+        return stringBuilder.toString();
+    }
 }

+ 208 - 0
ruoyi-system/src/main/java/com/ruoyi/system/domain/TElectronicFence.java

@@ -0,0 +1,208 @@
+package com.ruoyi.system.domain;
+
+import java.util.Date;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 【请填写功能名称】对象 t_electronic_fence
+ *
+ * @author ruoyi
+ * @date 2023-09-14
+ */
+public class TElectronicFence extends BaseEntity {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * id
+     */
+    private Long id;
+
+    /**
+     * 围栏昵称
+     */
+    @Excel(name = "围栏昵称")
+    private String name;
+
+    /**
+     * 开始时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "开始时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date startTime;
+
+    /**
+     * 结束时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "结束时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date endTime;
+
+    /**
+     * 围栏状态:(0:关闭 1:开启)
+     */
+    @Excel(name = "围栏状态:", readConverterExp = "0=:关闭,1=:开启")
+    private Integer eState;
+
+    /**
+     * 围栏开启状态(0:默认 1:禁止离开 2:禁止进入)
+     */
+    @Excel(name = "围栏开启状态", readConverterExp = "0=:默认,1=:禁止离开,2=:禁止进入")
+    private Integer eType;
+
+    /**
+     * 描述
+     */
+    @Excel(name = "描述")
+    private String eDesc;
+
+    /**
+     * 高德围栏服务的唯一ID
+     */
+    @Excel(name = "高德围栏服务的唯一ID")
+    private String gfid;
+
+    /**
+     * 0:默认 1:删除
+     */
+    @Excel(name = "0:默认 1:删除")
+    private Integer delState;
+
+    /**
+     * 用户id
+     */
+    @Excel(name = "用户id")
+    private Long userId;
+
+    /**
+     * 设备表id
+     */
+    @Excel(name = "设备表id")
+    private Long deviceId;
+
+    /**
+     * 高德电子围栏服务表id
+     */
+    @Excel(name = "高德电子围栏服务表id")
+    private Long serviceId;
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setStartTime(Date startTime) {
+        this.startTime = startTime;
+    }
+
+    public Date getStartTime() {
+        return startTime;
+    }
+
+    public void setEndTime(Date endTime) {
+        this.endTime = endTime;
+    }
+
+    public Date getEndTime() {
+        return endTime;
+    }
+
+    public void seteState(Integer eState) {
+        this.eState = eState;
+    }
+
+    public Integer geteState() {
+        return eState;
+    }
+
+    public void seteType(Integer eType) {
+        this.eType = eType;
+    }
+
+    public Integer geteType() {
+        return eType;
+    }
+
+    public String geteDesc() {
+        return eDesc;
+    }
+
+    public void seteDesc(String eDesc) {
+        this.eDesc = eDesc;
+    }
+
+    public void setGfid(String gfid) {
+        this.gfid = gfid;
+    }
+
+    public String getGfid() {
+        return gfid;
+    }
+
+    public void setDelState(Integer delState) {
+        this.delState = delState;
+    }
+
+    public Integer getDelState() {
+        return delState;
+    }
+
+    public void setUserId(Long userId) {
+        this.userId = userId;
+    }
+
+    public Long getUserId() {
+        return userId;
+    }
+
+    public void setDeviceId(Long deviceId) {
+        this.deviceId = deviceId;
+    }
+
+    public Long getDeviceId() {
+        return deviceId;
+    }
+
+    public void setServiceId(Long serviceId) {
+        this.serviceId = serviceId;
+    }
+
+    public Long getServiceId() {
+        return serviceId;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
+                .append("id", getId())
+                .append("name", getName())
+                .append("startTime", getStartTime())
+                .append("endTime", getEndTime())
+                .append("updateTime", getUpdateTime())
+                .append("createTime", getCreateTime())
+                .append("eState", geteState())
+                .append("eType", geteType())
+                .append("desc", geteDesc())
+                .append("gfid", getGfid())
+                .append("delState", getDelState())
+                .append("userId", getUserId())
+                .append("deviceId", getDeviceId())
+                .append("serviceId", getServiceId())
+                .toString();
+    }
+}

+ 81 - 0
ruoyi-system/src/main/java/com/ruoyi/system/domain/TElectronicFenceKey.java

@@ -0,0 +1,81 @@
+package com.ruoyi.system.domain;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 【请填写功能名称】对象 t_electronic_fence_key
+ * 
+ * @author ruoyi
+ * @date 2023-09-14
+ */
+public class TElectronicFenceKey extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** id */
+    private Long id;
+
+    /** 高德电子围栏key */
+    @Excel(name = "高德电子围栏key")
+    private String amapKey;
+
+    /** 高德电子围栏key名 */
+    @Excel(name = "高德电子围栏key名")
+    private String amapName;
+
+    /** 高德电子围栏key描述 */
+    @Excel(name = "高德电子围栏key描述")
+    private String amapDesc;
+
+    public void setId(Long id) 
+    {
+        this.id = id;
+    }
+
+    public Long getId() 
+    {
+        return id;
+    }
+    public void setAmapKey(String amapKey) 
+    {
+        this.amapKey = amapKey;
+    }
+
+    public String getAmapKey() 
+    {
+        return amapKey;
+    }
+    public void setAmapName(String amapName) 
+    {
+        this.amapName = amapName;
+    }
+
+    public String getAmapName() 
+    {
+        return amapName;
+    }
+    public void setAmapDesc(String amapDesc) 
+    {
+        this.amapDesc = amapDesc;
+    }
+
+    public String getAmapDesc() 
+    {
+        return amapDesc;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("amapKey", getAmapKey())
+            .append("createTime", getCreateTime())
+            .append("updateTime", getUpdateTime())
+            .append("amapName", getAmapName())
+            .append("amapDesc", getAmapDesc())
+            .toString();
+    }
+}

+ 95 - 0
ruoyi-system/src/main/java/com/ruoyi/system/domain/TElectronicFenceService.java

@@ -0,0 +1,95 @@
+package com.ruoyi.system.domain;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 【请填写功能名称】对象 t_electronic_fence_service
+ * 
+ * @author ruoyi
+ * @date 2023-09-14
+ */
+public class TElectronicFenceService extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** id */
+    private Long id;
+
+    /** 高德电子围栏key表id */
+    @Excel(name = "高德电子围栏key表id")
+    private Long keyId;
+
+    /** 高德电子围栏key下增加Service */
+    @Excel(name = "高德电子围栏key下增加Service")
+    private String amapSid;
+
+    /** 高德电子围栏key下增加Service名 */
+    @Excel(name = "高德电子围栏key下增加Service名")
+    private String amapName;
+
+    /** 高德电子围栏key下增加Service名 */
+    @Excel(name = "高德电子围栏key下增加Service名")
+    private String amapDesc;
+
+    public void setId(Long id) 
+    {
+        this.id = id;
+    }
+
+    public Long getId() 
+    {
+        return id;
+    }
+    public void setKeyId(Long keyId) 
+    {
+        this.keyId = keyId;
+    }
+
+    public Long getKeyId() 
+    {
+        return keyId;
+    }
+    public void setAmapSid(String amapSid) 
+    {
+        this.amapSid = amapSid;
+    }
+
+    public String getAmapSid() 
+    {
+        return amapSid;
+    }
+    public void setAmapName(String amapName) 
+    {
+        this.amapName = amapName;
+    }
+
+    public String getAmapName() 
+    {
+        return amapName;
+    }
+    public void setAmapDesc(String amapDesc) 
+    {
+        this.amapDesc = amapDesc;
+    }
+
+    public String getAmapDesc() 
+    {
+        return amapDesc;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("keyId", getKeyId())
+            .append("amapSid", getAmapSid())
+            .append("createTime", getCreateTime())
+            .append("updateTime", getUpdateTime())
+            .append("amapName", getAmapName())
+            .append("amapDesc", getAmapDesc())
+            .toString();
+    }
+}

+ 22 - 0
ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/AMapGeoFenceDto.java

@@ -0,0 +1,22 @@
+package com.ruoyi.system.domain.dto;
+
+/**
+ * @ClassName: AMapGeoFenceDto
+ * @Author: 于学智
+ * @Description:
+ * @CreateDate: 2023/9/14 0:34
+ * @Version: 1.0
+ * @E-mail:18722650553@139.com
+ * @Link:https://github.com/18722650553
+ */
+public class AMapGeoFenceDto {
+    private String gfid;
+
+    public String getGfid() {
+        return gfid;
+    }
+
+    public void setGfid(String gfid) {
+        this.gfid = gfid;
+    }
+}

+ 48 - 0
ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/AMapTrackDto.java

@@ -0,0 +1,48 @@
+package com.ruoyi.system.domain.dto;
+
+import com.ruoyi.common.core.domain.BaseEntity;
+
+import java.util.List;
+
+/**
+ * @ClassName: AMapTrackDto
+ * @Author: 于学智
+ * @Description:
+ * @CreateDate: 2023/9/13 22:10
+ * @Version: 1.0
+ * @E-mail:18722650553@139.com
+ * @Link:https://github.com/18722650553
+ */
+public class AMapTrackDto {
+
+    private List<ResultsDTO> results;
+
+    public List<ResultsDTO> getResults() {
+        return results;
+    }
+
+    public void setResults(List<ResultsDTO> results) {
+        this.results = results;
+    }
+
+    public static class ResultsDTO {
+        private String sid;
+        private String name;
+
+        public String getSid() {
+            return sid;
+        }
+
+        public void setSid(String sid) {
+            this.sid = sid;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public void setName(String name) {
+            this.name = name;
+        }
+    }
+}

+ 45 - 0
ruoyi-system/src/main/java/com/ruoyi/system/domain/enums/ElectronicFenceEnum.java

@@ -0,0 +1,45 @@
+package com.ruoyi.system.domain.enums;
+
+/**
+ * @ClassName: ElectronicFenceEnum
+ * @Author: 于学智
+ * @Description: 高德围栏类型
+ * @CreateDate: 2023/9/14 9:37
+ * @Version: 1.0
+ * @E-mail:18722650553@139.com
+ * @Link:https://github.com/18722650553
+ */
+public enum ElectronicFenceEnum {
+    /**
+     * 围栏-圆形
+     */
+    ELECTRONIC_FENCE_CIRCLE(0, "圆形围栏"),
+    /**
+     * 围栏-多边形围栏
+     */
+    ELECTRONIC_FENCE_POLYGON(1, "多边形围栏"),
+    /**
+     * 围栏-线形围栏
+     */
+    ELECTRONIC_FENCE_POLYLINE(2, "线形围栏"),
+    /**
+     * 围栏-行政区划围栏
+     */
+    ELECTRONIC_FENCE_DISTRICT(2, "行政区划围栏");
+    private final int key;
+
+    private final String value;
+
+    ElectronicFenceEnum(int key, String value) {
+        this.key = key;
+        this.value = value;
+    }
+
+    public int getKey() {
+        return key;
+    }
+
+    public String getValue() {
+        return value;
+    }
+}

+ 95 - 0
ruoyi-system/src/main/java/com/ruoyi/system/domain/to/AMapBaseTo.java

@@ -0,0 +1,95 @@
+package com.ruoyi.system.domain.to;
+
+import javax.validation.constraints.NotBlank;
+import java.util.StringJoiner;
+
+/**
+ * @ClassName: AMapBaseTo
+ * @Author: 于学智
+ * @Description:
+ * @CreateDate: 2023/9/14 17:35
+ * @Version: 1.0
+ * @E-mail:18722650553@139.com
+ * @Link:https://github.com/18722650553
+ */
+public class AMapBaseTo {
+    /**
+     * 高德key 用户在高德地图官网申请Web服务API类型Key 必填
+     */
+    @NotBlank(message = "高德Key禁止为空!")
+    private String key;
+
+    /**
+     * 服务唯一编号 sid为猎鹰service唯一编号 必填
+     */
+    @NotBlank(message = "服务唯一编号sid禁止为空!")
+    private String sid;
+
+    /**
+     * 围栏id  围栏唯一标识,指定要更新的围栏 必填
+     */
+    @NotBlank(message = "围栏gfid禁止为空!")
+    private String gfid;
+
+    /**
+     * 围栏名称 在同一个 sid 下不可重复,不可为空。 支持中文、英文大小字母、英文下划线"_"、英文横线"-"和数字,长度不大于128个字符 必填
+     */
+    @NotBlank(message = "围栏名称禁止为空!")
+    private String name;
+
+    /**
+     * 围栏描述 支持中文、英文大小字母、英文下划线"_"、英文横线"-"和数字,长度不大于128个字符 非
+     */
+    private String desc;
+
+    public String getKey() {
+        return key;
+    }
+
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+    public String getSid() {
+        return sid;
+    }
+
+    public void setSid(String sid) {
+        this.sid = sid;
+    }
+
+    public String getGfid() {
+        return gfid;
+    }
+
+    public void setGfid(String gfid) {
+        this.gfid = gfid;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
+
+    @Override
+    public String toString() {
+        return new StringJoiner(", ", AMapBaseTo.class.getSimpleName() + "[", "]")
+                .add("key='" + key + "'")
+                .add("sid='" + sid + "'")
+                .add("gfid='" + gfid + "'")
+                .add("name='" + name + "'")
+                .add("desc='" + desc + "'")
+                .toString();
+    }
+}

+ 52 - 0
ruoyi-system/src/main/java/com/ruoyi/system/domain/to/AMapUpdateCircleTo.java

@@ -0,0 +1,52 @@
+package com.ruoyi.system.domain.to;
+
+import javax.validation.constraints.NotBlank;
+import java.util.StringJoiner;
+
+/**
+ * @ClassName: AMapUpdateCircleTo
+ * @Author: 于学智
+ * @Description: 高德地图更新圆形围栏TO
+ * @CreateDate: 2023/9/14 16:19
+ * @Version: 1.0
+ * @E-mail:18722650553@139.com
+ * @Link:https://github.com/18722650553
+ */
+public class AMapUpdateCircleTo extends AMapBaseTo {
+
+    /**
+     * 围栏中心点坐标 格式X,Y 必填
+     */
+    @NotBlank(message = "围栏中心点坐标禁止为空!")
+    private String center;
+
+    /**
+     * 围栏半径 单位:米,整数,取值范[1,50000] 必填
+     */
+    @NotBlank(message = "围栏半径禁止为空!")
+    private String radius;
+
+    public String getCenter() {
+        return center;
+    }
+
+    public void setCenter(String center) {
+        this.center = center;
+    }
+
+    public String getRadius() {
+        return radius;
+    }
+
+    public void setRadius(String radius) {
+        this.radius = radius;
+    }
+
+    @Override
+    public String toString() {
+        return new StringJoiner(", ", AMapUpdateCircleTo.class.getSimpleName() + "[", "]")
+                .add("center='" + center + "'")
+                .add("radius='" + radius + "'")
+                .toString();
+    }
+}

+ 36 - 0
ruoyi-system/src/main/java/com/ruoyi/system/domain/to/AMapUpdateDistrictTo.java

@@ -0,0 +1,36 @@
+package com.ruoyi.system.domain.to;
+
+import javax.validation.constraints.NotBlank;
+import java.util.StringJoiner;
+
+/**
+ * @ClassName: AMapUpdateDistrictTo
+ * @Author: 于学智
+ * @Description: 高德地图更新行政区划围栏TO
+ * @CreateDate: 2023/9/14 16:19
+ * @Version: 1.0
+ * @E-mail:18722650553@139.com
+ * @Link:https://github.com/18722650553
+ */
+public class AMapUpdateDistrictTo extends AMapBaseTo {
+    /**
+     * 行政区划编码 参考行政区划编码表 必填
+     */
+    @NotBlank(message = "围栏行政区划编码禁止为空!")
+    private String adcode;
+
+    public String getAdcode() {
+        return adcode;
+    }
+
+    public void setAdcode(String adcode) {
+        this.adcode = adcode;
+    }
+
+    @Override
+    public String toString() {
+        return new StringJoiner(", ", AMapUpdateDistrictTo.class.getSimpleName() + "[", "]")
+                .add("adcode='" + adcode + "'")
+                .toString();
+    }
+}

+ 52 - 0
ruoyi-system/src/main/java/com/ruoyi/system/domain/to/AMapUpdatePolyLineTo.java

@@ -0,0 +1,52 @@
+package com.ruoyi.system.domain.to;
+
+import javax.validation.constraints.NotBlank;
+import java.util.StringJoiner;
+
+/**
+ * @ClassName: AMapUpdatePolyLineTo
+ * @Author: 于学智
+ * @Description: 高德地图更新线形围栏TO
+ * @CreateDate: 2023/9/14 16:19
+ * @Version: 1.0
+ * @E-mail:18722650553@139.com
+ * @Link:https://github.com/18722650553
+ */
+public class AMapUpdatePolyLineTo extends AMapBaseTo {
+
+    /**
+     * 多边形顶点坐标 格式 X1,Y1;X2,Y2; 必填
+     */
+    @NotBlank(message = "围栏中心点坐标禁止为空!")
+    private String points;
+
+    /**
+     * 沿线偏移距离 单位:米 取值范围 [1,300] 必填
+     */
+    @NotBlank(message = "围栏中心点坐标禁止为空!")
+    private String bufferradius;
+
+    public String getPoints() {
+        return points;
+    }
+
+    public void setPoints(String points) {
+        this.points = points;
+    }
+
+    public String getBufferradius() {
+        return bufferradius;
+    }
+
+    public void setBufferradius(String bufferradius) {
+        this.bufferradius = bufferradius;
+    }
+
+    @Override
+    public String toString() {
+        return new StringJoiner(", ", AMapUpdatePolyLineTo.class.getSimpleName() + "[", "]")
+                .add("points='" + points + "'")
+                .add("bufferradius='" + bufferradius + "'")
+                .toString();
+    }
+}

+ 37 - 0
ruoyi-system/src/main/java/com/ruoyi/system/domain/to/AMapUpdatePolygonTo.java

@@ -0,0 +1,37 @@
+package com.ruoyi.system.domain.to;
+
+import javax.validation.constraints.NotBlank;
+import java.util.StringJoiner;
+
+/**
+ * @ClassName: AMapUpdatePolygonTo
+ * @Author: 于学智
+ * @Description: 高德地图更新多边形围栏TO
+ * @CreateDate: 2023/9/14 16:19
+ * @Version: 1.0
+ * @E-mail:18722650553@139.com
+ * @Link:https://github.com/18722650553
+ */
+public class AMapUpdatePolygonTo extends AMapBaseTo {
+
+    /**
+     * 多边形顶点坐标 格式 X1,Y1;X2,Y2; 必填
+     */
+    @NotBlank(message = "围栏中心点坐标禁止为空!")
+    private String points;
+
+    public String getPoints() {
+        return points;
+    }
+
+    public void setPoints(String points) {
+        this.points = points;
+    }
+
+    @Override
+    public String toString() {
+        return new StringJoiner(", ", AMapUpdatePolygonTo.class.getSimpleName() + "[", "]")
+                .add("points='" + points + "'")
+                .toString();
+    }
+}

+ 277 - 0
ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/ElectronicFenceVo.java

@@ -0,0 +1,277 @@
+package com.ruoyi.system.domain.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import javax.validation.constraints.*;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.StringJoiner;
+
+/**
+ * @ClassName: ElectronicFenceVo
+ * @Author: 于学智
+ * @Description: 电子围栏VO
+ * @CreateDate: 2023/9/13 16:31
+ * @Version: 1.0
+ * @E-mail:18722650553@139.com
+ * @Link:https://github.com/18722650553
+ */
+public class ElectronicFenceVo implements Serializable {
+    /**
+     * 围栏id
+     */
+    private Long id;
+    /**
+     * 高德key 用户在高德地图官网申请Web服务API类型Key 必填
+     */
+    private String key;
+
+    /**
+     * 服务唯一编号 sid为猎鹰service唯一编号 必填
+     */
+    private String sid;
+
+    /**
+     * 围栏名称 在同一个 sid 下不可重复,不可为空。 支持中文、英文大小字母、英文下划线"_"、英文横线"-"和数字,长度不大于128个字符 必填
+     */
+    @NotBlank(message = "围栏名称禁止为空!")
+    private String name;
+
+    /**
+     * 围栏中心点坐标 格式X,Y 必填
+     */
+    private String center;
+
+    /**
+     * 沿线偏移距离 单位:米 取值范围 [1,300] 必填
+     */
+    private String bufferradius;
+
+    /**
+     * 行政区划编码 参考行政区划编码表 必填
+     */
+    private String adcode;
+
+    /**
+     * 围栏多边形顶点坐标 格式X1,Y1;X2,Y2; 必填
+     */
+    private String points;
+
+    /**
+     * 围栏半径 单位:米,整数,取值范[1,50000] 必填
+     */
+    private String radius;
+
+    /**
+     * 围栏描述 支持中文、英文大小字母、英文下划线"_"、英文横线"-"和数字,长度不大于128个字符 否
+     */
+    private String desc;
+
+    /**
+     * 围栏-圆形-0
+     * 围栏-多边形围栏-1
+     * 围栏-线形围栏-2
+     * 围栏-行政区划围栏-3
+     */
+    @Max(value = 3, message = "围栏类型错误!")
+    @Min(value = 0, message = "围栏类型错误!")
+    @NotNull(message = "围栏类型禁止为空!")
+    private Integer geofence_type;
+
+    /**
+     * 围栏开始时间
+     */
+    @NotNull(message = "围栏开始时间禁止为空!")
+    private Long start_time;
+    /**
+     * 围栏结束时间
+     */
+    @NotNull(message = "围栏结束时间禁止为空!")
+    private Long end_time;
+    /**
+     * 围栏状态 0:关闭 1:开启
+     */
+    @Max(value = 1, message = "围栏状态错误!")
+    @Min(value = 0, message = "围栏状态错误!")
+    @NotNull(message = "围栏状态禁止为空!")
+    private Integer state;
+    /**
+     * 围栏开启状态(0:默认 1:禁止离开 2:禁止进入)
+     */
+    @Max(value = 2, message = "围栏开启状态错误!")
+    @Min(value = 0, message = "围栏开启状态错误!")
+    @NotNull(message = "围栏开启状态禁止为空!")
+    private Integer type;
+    /**
+     * 用户ID
+     */
+    private Long usdId;
+    /**
+     * 设备ID
+     */
+    @NotNull(message = "设备ID禁止为空!")
+    private Long deviceId;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getKey() {
+        return key;
+    }
+
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+    public String getSid() {
+        return sid;
+    }
+
+    public void setSid(String sid) {
+        this.sid = sid;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getCenter() {
+        return center;
+    }
+
+    public void setCenter(String center) {
+        this.center = center;
+    }
+
+    public String getBufferradius() {
+        return bufferradius;
+    }
+
+    public void setBufferradius(String bufferradius) {
+        this.bufferradius = bufferradius;
+    }
+
+    public String getAdcode() {
+        return adcode;
+    }
+
+    public void setAdcode(String adcode) {
+        this.adcode = adcode;
+    }
+
+    public String getPoints() {
+        return points;
+    }
+
+    public void setPoints(String points) {
+        this.points = points;
+    }
+
+    public String getRadius() {
+        return radius;
+    }
+
+    public void setRadius(String radius) {
+        this.radius = radius;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
+
+    public Integer getGeofence_type() {
+        return geofence_type;
+    }
+
+    public void setGeofence_type(Integer geofence_type) {
+        this.geofence_type = geofence_type;
+    }
+
+    public Long getStart_time() {
+        return start_time;
+    }
+
+    public void setStart_time(Long start_time) {
+        this.start_time = start_time;
+    }
+
+    public Long getEnd_time() {
+        return end_time;
+    }
+
+    public void setEnd_time(Long end_time) {
+        this.end_time = end_time;
+    }
+
+    public Integer getState() {
+        return state;
+    }
+
+    public void setState(Integer state) {
+        this.state = state;
+    }
+
+    public Integer getType() {
+        return type;
+    }
+
+    public void setType(Integer type) {
+        this.type = type;
+    }
+
+    public Long getDeviceId() {
+        return deviceId;
+    }
+
+    public void setDeviceId(Long deviceId) {
+        this.deviceId = deviceId;
+    }
+
+    public Long getUsdId() {
+        return usdId;
+    }
+
+    public void setUsdId(Long usdId) {
+        this.usdId = usdId;
+    }
+
+    @Override
+    public String toString() {
+        return new StringJoiner(", ", ElectronicFenceVo.class.getSimpleName() + "[", "]")
+                .add("id=" + id)
+                .add("key='" + key + "'")
+                .add("sid='" + sid + "'")
+                .add("name='" + name + "'")
+                .add("center='" + center + "'")
+                .add("bufferradius='" + bufferradius + "'")
+                .add("adcode='" + adcode + "'")
+                .add("points='" + points + "'")
+                .add("radius='" + radius + "'")
+                .add("desc='" + desc + "'")
+                .add("geofence_type=" + geofence_type)
+                .add("start_time=" + start_time)
+                .add("end_time=" + end_time)
+                .add("state=" + state)
+                .add("type=" + type)
+                .add("usdId=" + usdId)
+                .add("deviceId=" + deviceId)
+                .toString();
+    }
+}

+ 63 - 0
ruoyi-system/src/main/java/com/ruoyi/system/mapper/TElectronicFenceKeyMapper.java

@@ -0,0 +1,63 @@
+package com.ruoyi.system.mapper;
+
+import java.util.List;
+import com.ruoyi.system.domain.TElectronicFenceKey;
+
+/**
+ * 【请填写功能名称】Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2023-09-14
+ */
+public interface TElectronicFenceKeyMapper 
+{
+    /**
+     * 查询【请填写功能名称】
+     * 
+     * @param id 【请填写功能名称】主键
+     * @return 【请填写功能名称】
+     */
+    public TElectronicFenceKey selectTElectronicFenceKeyById(Long id);
+
+    /**
+     * 查询【请填写功能名称】列表
+     * 
+     * @param tElectronicFenceKey 【请填写功能名称】
+     * @return 【请填写功能名称】集合
+     */
+    public List<TElectronicFenceKey> selectTElectronicFenceKeyList(TElectronicFenceKey tElectronicFenceKey);
+
+    /**
+     * 新增【请填写功能名称】
+     * 
+     * @param tElectronicFenceKey 【请填写功能名称】
+     * @return 结果
+     */
+    public int insertTElectronicFenceKey(TElectronicFenceKey tElectronicFenceKey);
+
+    /**
+     * 修改【请填写功能名称】
+     * 
+     * @param tElectronicFenceKey 【请填写功能名称】
+     * @return 结果
+     */
+    public int updateTElectronicFenceKey(TElectronicFenceKey tElectronicFenceKey);
+
+    /**
+     * 删除【请填写功能名称】
+     * 
+     * @param id 【请填写功能名称】主键
+     * @return 结果
+     */
+    public int deleteTElectronicFenceKeyById(Long id);
+
+    /**
+     * 批量删除【请填写功能名称】
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteTElectronicFenceKeyByIds(Long[] ids);
+
+    List<TElectronicFenceKey> selectTElectronicFenceKey();
+}

+ 81 - 0
ruoyi-system/src/main/java/com/ruoyi/system/mapper/TElectronicFenceMapper.java

@@ -0,0 +1,81 @@
+package com.ruoyi.system.mapper;
+
+import java.util.List;
+
+import com.ruoyi.system.domain.TElectronicFence;
+
+/**
+ * 【请填写功能名称】Mapper接口
+ *
+ * @author ruoyi
+ * @date 2023-09-14
+ */
+public interface TElectronicFenceMapper {
+    /**
+     * 查询【请填写功能名称】
+     *
+     * @param id 【请填写功能名称】主键
+     * @return 【请填写功能名称】
+     */
+    public TElectronicFence selectTElectronicFenceById(Long id);
+
+    /**
+     * 查询【请填写功能名称】列表
+     *
+     * @param tElectronicFence 【请填写功能名称】
+     * @return 【请填写功能名称】集合
+     */
+    public List<TElectronicFence> selectTElectronicFenceList(TElectronicFence tElectronicFence);
+
+    /**
+     * 新增【请填写功能名称】
+     *
+     * @param tElectronicFence 【请填写功能名称】
+     * @return 结果
+     */
+    public int insertTElectronicFence(TElectronicFence tElectronicFence);
+
+    /**
+     * 修改【请填写功能名称】
+     *
+     * @param tElectronicFence 【请填写功能名称】
+     * @return 结果
+     */
+    public int updateTElectronicFence(TElectronicFence tElectronicFence);
+
+    /**
+     * 删除【请填写功能名称】
+     *
+     * @param id 【请填写功能名称】主键
+     * @return 结果
+     */
+    public int deleteTElectronicFenceById(Long id);
+
+    /**
+     * 批量删除【请填写功能名称】
+     *
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteTElectronicFenceByIds(Long[] ids);
+
+    /**
+     * 通过deviceId获取围栏
+     *
+     * @param deviceId
+     * @return
+     */
+    List<TElectronicFence> selectTElectronicFenceListByDeviceId(Long deviceId);
+
+    int deleteTElectronicFenceStateByIds(Long[] ids);
+
+    /**
+     * 通过删除状态查询围栏
+     *
+     * @param delState
+     * @return
+     */
+    List<TElectronicFence> selectTElectronicFenceByDelState(Integer delState);
+
+    void deleteTElectronicFenceByGfids(Long[] gfids);
+}

+ 63 - 0
ruoyi-system/src/main/java/com/ruoyi/system/mapper/TElectronicFenceServiceMapper.java

@@ -0,0 +1,63 @@
+package com.ruoyi.system.mapper;
+
+import java.util.List;
+import com.ruoyi.system.domain.TElectronicFenceService;
+
+/**
+ * 【请填写功能名称】Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2023-09-14
+ */
+public interface TElectronicFenceServiceMapper 
+{
+    /**
+     * 查询【请填写功能名称】
+     * 
+     * @param id 【请填写功能名称】主键
+     * @return 【请填写功能名称】
+     */
+    public TElectronicFenceService selectTElectronicFenceServiceById(Long id);
+
+    /**
+     * 查询【请填写功能名称】列表
+     * 
+     * @param tElectronicFenceService 【请填写功能名称】
+     * @return 【请填写功能名称】集合
+     */
+    public List<TElectronicFenceService> selectTElectronicFenceServiceList(TElectronicFenceService tElectronicFenceService);
+
+    /**
+     * 新增【请填写功能名称】
+     * 
+     * @param tElectronicFenceService 【请填写功能名称】
+     * @return 结果
+     */
+    public int insertTElectronicFenceService(TElectronicFenceService tElectronicFenceService);
+
+    /**
+     * 修改【请填写功能名称】
+     * 
+     * @param tElectronicFenceService 【请填写功能名称】
+     * @return 结果
+     */
+    public int updateTElectronicFenceService(TElectronicFenceService tElectronicFenceService);
+
+    /**
+     * 删除【请填写功能名称】
+     * 
+     * @param id 【请填写功能名称】主键
+     * @return 结果
+     */
+    public int deleteTElectronicFenceServiceById(Long id);
+
+    /**
+     * 批量删除【请填写功能名称】
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteTElectronicFenceServiceByIds(Long[] ids);
+
+    List<TElectronicFenceService> selectTElectronicFenceServiceByKeyId(Long keyId);
+}

+ 75 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/ITElectronicFenceKeyService.java

@@ -0,0 +1,75 @@
+package com.ruoyi.system.service;
+
+import java.util.List;
+
+import com.ruoyi.system.domain.TElectronicFenceKey;
+import com.ruoyi.system.domain.TElectronicFenceService;
+
+/**
+ * 【请填写功能名称】Service接口
+ *
+ * @author ruoyi
+ * @date 2023-09-14
+ */
+public interface ITElectronicFenceKeyService {
+    /**
+     * 查询【请填写功能名称】
+     *
+     * @param id 【请填写功能名称】主键
+     * @return 【请填写功能名称】
+     */
+    public TElectronicFenceKey selectTElectronicFenceKeyById(Long id);
+
+    /**
+     * 查询【请填写功能名称】列表
+     *
+     * @param tElectronicFenceKey 【请填写功能名称】
+     * @return 【请填写功能名称】集合
+     */
+    public List<TElectronicFenceKey> selectTElectronicFenceKeyList(TElectronicFenceKey tElectronicFenceKey);
+
+    /**
+     * 新增【请填写功能名称】
+     *
+     * @param tElectronicFenceKey 【请填写功能名称】
+     * @return 结果
+     */
+    public int insertTElectronicFenceKey(TElectronicFenceKey tElectronicFenceKey);
+
+    /**
+     * 修改【请填写功能名称】
+     *
+     * @param tElectronicFenceKey 【请填写功能名称】
+     * @return 结果
+     */
+    public int updateTElectronicFenceKey(TElectronicFenceKey tElectronicFenceKey);
+
+    /**
+     * 批量删除【请填写功能名称】
+     *
+     * @param ids 需要删除的【请填写功能名称】主键集合
+     * @return 结果
+     */
+    public int deleteTElectronicFenceKeyByIds(Long[] ids);
+
+    /**
+     * 删除【请填写功能名称】信息
+     *
+     * @param id 【请填写功能名称】主键
+     * @return 结果
+     */
+    public int deleteTElectronicFenceKeyById(Long id);
+
+    /**
+     * 获取库中所有的key
+     * @return
+     */
+    List<TElectronicFenceKey> selectTElectronicFenceKey();
+
+    /**
+     * 获取一个可用Key
+     *
+     * @return
+     */
+    TElectronicFenceKey selectAccessAvailableElectronicFenceKey();
+}

+ 81 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/ITElectronicFenceService.java

@@ -0,0 +1,81 @@
+package com.ruoyi.system.service;
+
+import java.util.List;
+
+import com.ruoyi.system.domain.TElectronicFence;
+import com.ruoyi.system.domain.vo.ElectronicFenceVo;
+
+/**
+ * 【请填写功能名称】Service接口
+ *
+ * @author ruoyi
+ * @date 2023-09-14
+ */
+public interface ITElectronicFenceService {
+    /**
+     * 查询【请填写功能名称】
+     *
+     * @param id 【请填写功能名称】主键
+     * @return 【请填写功能名称】
+     */
+    public TElectronicFence selectTElectronicFenceById(Long id);
+
+    /**
+     * 查询【请填写功能名称】列表
+     *
+     * @param tElectronicFence 【请填写功能名称】
+     * @return 【请填写功能名称】集合
+     */
+    public List<TElectronicFence> selectTElectronicFenceList(TElectronicFence tElectronicFence);
+
+    /**
+     * 新增【请填写功能名称】
+     *
+     * @param tElectronicFence 【请填写功能名称】
+     * @return 结果
+     */
+    public int insertTElectronicFence(TElectronicFence tElectronicFence);
+
+    /**
+     * 修改【请填写功能名称】
+     *
+     * @param tElectronicFence 【请填写功能名称】
+     * @return 结果
+     */
+    public int updateTElectronicFence(TElectronicFence tElectronicFence);
+
+    /**
+     * 批量删除【请填写功能名称】
+     *
+     * @param ids 需要删除的【请填写功能名称】主键集合
+     * @return 结果
+     */
+    public int deleteTElectronicFenceByIds(Long[] ids);
+
+    /**
+     * 删除【请填写功能名称】信息
+     *
+     * @param id 【请填写功能名称】主键
+     * @return 结果
+     */
+    public int deleteTElectronicFenceById(Long id);
+
+    int insertTElectronicFenceVo(ElectronicFenceVo electronicFenceVo);
+
+    /**
+     * 通过deviceId获取围栏列表
+     *
+     * @param deviceId
+     * @return
+     */
+    List<TElectronicFence> selectTElectronicFenceListByDeviceId(Long deviceId);
+
+    /**
+     * 通过围栏id更新
+     *
+     * @param tElectronicFenceEditVo
+     * @return
+     */
+    int updateTElectronicFenceEditVo(ElectronicFenceVo tElectronicFenceEditVo);
+
+}

+ 77 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/ITElectronicFenceServiceService.java

@@ -0,0 +1,77 @@
+package com.ruoyi.system.service;
+
+import java.util.List;
+
+import com.ruoyi.system.domain.TElectronicFenceService;
+
+/**
+ * 【请填写功能名称】Service接口
+ *
+ * @author ruoyi
+ * @date 2023-09-14
+ */
+public interface ITElectronicFenceServiceService {
+    /**
+     * 查询【请填写功能名称】
+     *
+     * @param id 【请填写功能名称】主键
+     * @return 【请填写功能名称】
+     */
+    public TElectronicFenceService selectTElectronicFenceServiceById(Long id);
+
+    /**
+     * 查询【请填写功能名称】列表
+     *
+     * @param tElectronicFenceService 【请填写功能名称】
+     * @return 【请填写功能名称】集合
+     */
+    public List<TElectronicFenceService> selectTElectronicFenceServiceList(TElectronicFenceService tElectronicFenceService);
+
+    /**
+     * 新增【请填写功能名称】
+     *
+     * @param tElectronicFenceService 【请填写功能名称】
+     * @return 结果
+     */
+    public int insertTElectronicFenceService(TElectronicFenceService tElectronicFenceService);
+
+    /**
+     * 修改【请填写功能名称】
+     *
+     * @param tElectronicFenceService 【请填写功能名称】
+     * @return 结果
+     */
+    public int updateTElectronicFenceService(TElectronicFenceService tElectronicFenceService);
+
+    /**
+     * 批量删除【请填写功能名称】
+     *
+     * @param ids 需要删除的【请填写功能名称】主键集合
+     * @return 结果
+     */
+    public int deleteTElectronicFenceServiceByIds(Long[] ids);
+
+    /**
+     * 删除【请填写功能名称】信息
+     *
+     * @param id 【请填写功能名称】主键
+     * @return 结果
+     */
+    public int deleteTElectronicFenceServiceById(Long id);
+
+    /**
+     * 获取这个Key下所有的服务
+     *
+     * @param keyId
+     * @return
+     */
+    List<TElectronicFenceService> selectTElectronicFenceServiceByKeyId(Long keyId);
+
+    /**
+     * 获取一个可用服务
+     *
+     * @param keyId
+     * @return
+     */
+    TElectronicFenceService selectAccessAvailableElectronicFenceServiceByKeyId(Long keyId);
+}

+ 112 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TElectronicFenceKeyServiceImpl.java

@@ -0,0 +1,112 @@
+package com.ruoyi.system.service.impl;
+
+import java.util.List;
+
+import com.alibaba.fastjson.JSONObject;
+import com.ruoyi.common.utils.DateUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.system.mapper.TElectronicFenceKeyMapper;
+import com.ruoyi.system.domain.TElectronicFenceKey;
+import com.ruoyi.system.service.ITElectronicFenceKeyService;
+
+/**
+ * 【请填写功能名称】Service业务层处理
+ *
+ * @author ruoyi
+ * @date 2023-09-14
+ */
+@Service
+public class TElectronicFenceKeyServiceImpl implements ITElectronicFenceKeyService {
+    private static final Logger log = LoggerFactory.getLogger(TElectronicFenceKeyServiceImpl.class);
+    @Autowired
+    private TElectronicFenceKeyMapper tElectronicFenceKeyMapper;
+
+    /**
+     * 查询【请填写功能名称】
+     *
+     * @param id 【请填写功能名称】主键
+     * @return 【请填写功能名称】
+     */
+    @Override
+    public TElectronicFenceKey selectTElectronicFenceKeyById(Long id) {
+        return tElectronicFenceKeyMapper.selectTElectronicFenceKeyById(id);
+    }
+
+    /**
+     * 查询【请填写功能名称】列表
+     *
+     * @param tElectronicFenceKey 【请填写功能名称】
+     * @return 【请填写功能名称】
+     */
+    @Override
+    public List<TElectronicFenceKey> selectTElectronicFenceKeyList(TElectronicFenceKey tElectronicFenceKey) {
+        return tElectronicFenceKeyMapper.selectTElectronicFenceKeyList(tElectronicFenceKey);
+    }
+
+    /**
+     * 新增【请填写功能名称】
+     *
+     * @param tElectronicFenceKey 【请填写功能名称】
+     * @return 结果
+     */
+    @Override
+    public int insertTElectronicFenceKey(TElectronicFenceKey tElectronicFenceKey) {
+        tElectronicFenceKey.setCreateTime(DateUtils.getNowDate());
+        return tElectronicFenceKeyMapper.insertTElectronicFenceKey(tElectronicFenceKey);
+    }
+
+    /**
+     * 修改【请填写功能名称】
+     *
+     * @param tElectronicFenceKey 【请填写功能名称】
+     * @return 结果
+     */
+    @Override
+    public int updateTElectronicFenceKey(TElectronicFenceKey tElectronicFenceKey) {
+        tElectronicFenceKey.setUpdateTime(DateUtils.getNowDate());
+        return tElectronicFenceKeyMapper.updateTElectronicFenceKey(tElectronicFenceKey);
+    }
+
+    /**
+     * 批量删除【请填写功能名称】
+     *
+     * @param ids 需要删除的【请填写功能名称】主键
+     * @return 结果
+     */
+    @Override
+    public int deleteTElectronicFenceKeyByIds(Long[] ids) {
+        return tElectronicFenceKeyMapper.deleteTElectronicFenceKeyByIds(ids);
+    }
+
+    /**
+     * 删除【请填写功能名称】信息
+     *
+     * @param id 【请填写功能名称】主键
+     * @return 结果
+     */
+    @Override
+    public int deleteTElectronicFenceKeyById(Long id) {
+        return tElectronicFenceKeyMapper.deleteTElectronicFenceKeyById(id);
+    }
+
+    @Override
+    public List<TElectronicFenceKey> selectTElectronicFenceKey() {
+        return tElectronicFenceKeyMapper.selectTElectronicFenceKey();
+    }
+
+    @Override
+    public TElectronicFenceKey selectAccessAvailableElectronicFenceKey() {
+        //获取所有的Key
+        List<TElectronicFenceKey> tElectronicFenceKeys = tElectronicFenceKeyMapper.selectTElectronicFenceKey();
+        if (tElectronicFenceKeys != null && !tElectronicFenceKeys.isEmpty()) {
+            log.info("获取高德所有amap_key:{} .", JSONObject.toJSONString(tElectronicFenceKeys));
+            return tElectronicFenceKeys.get(0);
+        } else {
+            log.error("获取高德所有amap_key为空.");
+        }
+        return null;
+    }
+}

+ 815 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TElectronicFenceServiceImpl.java

@@ -0,0 +1,815 @@
+package com.ruoyi.system.service.impl;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.alibaba.fastjson.JSONObject;
+import com.ruoyi.common.constant.AMapConstants;
+import com.ruoyi.common.core.domain.AMapResult;
+import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.common.utils.bean.BeanUtils;
+import com.ruoyi.common.utils.http.HttpUtils;
+import com.ruoyi.system.domain.TElectronicFenceKey;
+import com.ruoyi.system.domain.TElectronicFenceService;
+import com.ruoyi.system.domain.to.AMapUpdateCircleTo;
+import com.ruoyi.system.domain.to.AMapUpdateDistrictTo;
+import com.ruoyi.system.domain.to.AMapUpdatePolyLineTo;
+import com.ruoyi.system.domain.to.AMapUpdatePolygonTo;
+import com.ruoyi.system.domain.vo.ElectronicFenceVo;
+import com.ruoyi.system.mapper.TElectronicFenceMapper;
+import com.ruoyi.system.service.ITElectronicFenceKeyService;
+import com.ruoyi.system.service.ITElectronicFenceServiceService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.system.domain.TElectronicFence;
+import com.ruoyi.system.service.ITElectronicFenceService;
+import org.springframework.validation.annotation.Validated;
+
+/**
+ * 【请填写功能名称】Service业务层处理
+ *
+ * @author ruoyi
+ * @date 2023-09-14
+ */
+@Service
+public class TElectronicFenceServiceImpl implements ITElectronicFenceService {
+    private static final Logger log = LoggerFactory.getLogger(TElectronicFenceServiceImpl.class);
+
+    @Autowired
+    private TElectronicFenceMapper tElectronicFenceMapper;
+    @Autowired
+    private ITElectronicFenceKeyService iElectronicFenceKeyService;
+    @Autowired
+    private ITElectronicFenceServiceService iElectronicFenceServiceService;
+
+    /**
+     * 查询【请填写功能名称】
+     *
+     * @param id 【请填写功能名称】主键
+     * @return 【请填写功能名称】
+     */
+    @Override
+    public TElectronicFence selectTElectronicFenceById(Long id) {
+        return tElectronicFenceMapper.selectTElectronicFenceById(id);
+    }
+
+    /**
+     * 查询【请填写功能名称】列表
+     *
+     * @param tElectronicFence 【请填写功能名称】
+     * @return 【请填写功能名称】
+     */
+    @Override
+    public List<TElectronicFence> selectTElectronicFenceList(TElectronicFence tElectronicFence) {
+        //查询未删除窗台
+        tElectronicFence.setDelState(1);
+        return tElectronicFenceMapper.selectTElectronicFenceList(tElectronicFence);
+    }
+
+    /**
+     * 新增【请填写功能名称】
+     *
+     * @param tElectronicFence 【请填写功能名称】
+     * @return 结果
+     */
+    @Override
+    public int insertTElectronicFence(TElectronicFence tElectronicFence) {
+        tElectronicFence.setCreateTime(DateUtils.getNowDate());
+        return tElectronicFenceMapper.insertTElectronicFence(tElectronicFence);
+    }
+
+    /**
+     * 修改【请填写功能名称】
+     *
+     * @param tElectronicFence 【请填写功能名称】
+     * @return 结果
+     */
+    @Override
+    public int updateTElectronicFence(TElectronicFence tElectronicFence) {
+        tElectronicFence.setUpdateTime(DateUtils.getNowDate());
+        return tElectronicFenceMapper.updateTElectronicFence(tElectronicFence);
+    }
+
+    /**
+     * 批量删除【请填写功能名称】
+     *
+     * @param ids 需要删除的【请填写功能名称】主键
+     * @return 结果
+     */
+    @Override
+    public int deleteTElectronicFenceByIds(Long[] ids) {
+        /**
+         * TODO 队列MQ删除高德围栏,现阶段直接更改围栏状态为删除
+         */
+        return tElectronicFenceMapper.deleteTElectronicFenceStateByIds(ids);
+    }
+
+    /**
+     * 删除【请填写功能名称】信息
+     *
+     * @param id 【请填写功能名称】主键
+     * @return 结果
+     */
+    @Override
+    public int deleteTElectronicFenceById(Long id) {
+        return tElectronicFenceMapper.deleteTElectronicFenceById(id);
+    }
+
+    @Override
+    public int insertTElectronicFenceVo(ElectronicFenceVo electronicFenceVo) {
+        if (electronicFenceVo.getGeofence_type() == 0) {
+            //围栏-圆形
+            return trackGeofenceAddCircle(electronicFenceVo);
+        } else if (electronicFenceVo.getGeofence_type() == 1) {
+            //围栏-多边形围栏
+            return trackGeofenceAddPolygon(electronicFenceVo);
+        } else if (electronicFenceVo.getGeofence_type() == 2) {
+            //围栏-线形围栏
+            return trackGeofenceAddPolyline(electronicFenceVo);
+        } else if (electronicFenceVo.getGeofence_type() == 3) {
+            //围栏-行政区划围栏
+            return trackGeofenceAddDistrict(electronicFenceVo);
+        } else {
+            log.error("创建围栏类型不匹配,类型:{}.", electronicFenceVo.getGeofence_type());
+            throw new ServiceException("创建围栏类型不匹配!");
+        }
+    }
+
+    @Override
+    public List<TElectronicFence> selectTElectronicFenceListByDeviceId(Long deviceId) {
+        return tElectronicFenceMapper.selectTElectronicFenceListByDeviceId(deviceId);
+    }
+
+    @Override
+    public int updateTElectronicFenceEditVo(ElectronicFenceVo tElectronicFenceEditVo) {
+        //校验围栏类型是否为空
+        if (tElectronicFenceEditVo.getGeofence_type() == null) {
+            log.error("更新围栏禁止围栏类型为空,id:{}.", tElectronicFenceEditVo.getId());
+            throw new ServiceException("更新围栏禁止围栏类型为空!");
+        }
+        //查询库中的围栏信息
+        TElectronicFence tElectronicFence = tElectronicFenceMapper.selectTElectronicFenceById(tElectronicFenceEditVo.getId());
+        if (tElectronicFence == null) {
+            log.error("获取本地围栏为空.");
+            throw new ServiceException("获取本地围栏为空!");
+        }
+        TElectronicFenceService fenceService = iElectronicFenceServiceService.selectTElectronicFenceServiceById(tElectronicFence.getServiceId());
+        if (fenceService == null) {
+            log.error("围栏对应的高德服务为空,围栏ID:{}.", tElectronicFence.getServiceId());
+            throw new ServiceException("围栏对应的高德服务为空!");
+        }
+        TElectronicFenceKey tElectronicFenceKey = iElectronicFenceKeyService.selectTElectronicFenceKeyById(fenceService.getKeyId());
+        if (tElectronicFenceKey == null) {
+            log.error("围栏对应的高德key为空,围栏ID:{}. 服务ID:{}", tElectronicFence.getId(), tElectronicFence.getServiceId());
+            throw new ServiceException("围栏对应的高德key为空!");
+        }
+        //更新数据库围栏信息
+        TElectronicFence fence = new TElectronicFence();
+        fence.setId(tElectronicFenceEditVo.getId());
+        //围栏昵称
+        if (!StringUtils.isEmpty(tElectronicFenceEditVo.getName())) {
+            fence.setName(tElectronicFenceEditVo.getName());
+        }
+        //围栏开始时间
+        if (tElectronicFenceEditVo.getStart_time() != null && tElectronicFenceEditVo.getStart_time() > 0) {
+            fence.setStartTime(new Date(tElectronicFenceEditVo.getStart_time()));
+        }
+        //围栏结束时间
+        if (tElectronicFenceEditVo.getEnd_time() != null && tElectronicFenceEditVo.getEnd_time() > 0) {
+            fence.setEndTime(new Date(tElectronicFenceEditVo.getEnd_time()));
+        }
+        //围栏状态:(0:关闭 1:开启)
+        if (tElectronicFenceEditVo.getState() != null && tElectronicFenceEditVo.getState() >= 0 && tElectronicFenceEditVo.getState() <= 1) {
+            fence.seteState(tElectronicFenceEditVo.getState());
+        }
+        //围栏开启状态(0:默认 1:禁止离开 2:禁止进入)
+        if (tElectronicFenceEditVo.getType() != null && tElectronicFenceEditVo.getState() >= 0 && tElectronicFenceEditVo.getState() <= 2) {
+            fence.seteType(tElectronicFenceEditVo.getType());
+        }
+        //描述
+        if (tElectronicFenceEditVo.getDesc() != null && !StringUtils.isEmpty(tElectronicFenceEditVo.getDesc())) {
+            fence.seteDesc(tElectronicFenceEditVo.getDesc());
+        }
+        //更新围栏
+        String gfid = null;
+        if (tElectronicFenceEditVo.getGeofence_type() == 0) {
+            //围栏-圆形
+            gfid = trackGeofenceUpdateCircle(tElectronicFenceEditVo, tElectronicFenceKey, fenceService, tElectronicFence);
+        } else if (tElectronicFenceEditVo.getGeofence_type() == 1) {
+            //围栏-多边形围栏
+            gfid = trackGeofenceUpdatePolygon(tElectronicFenceEditVo, tElectronicFenceKey, fenceService, tElectronicFence);
+        } else if (tElectronicFenceEditVo.getGeofence_type() == 2) {
+            //围栏-线形围栏
+            gfid = trackGeofenceUpdatePolyline(tElectronicFenceEditVo, tElectronicFenceKey, fenceService, tElectronicFence);
+        } else if (tElectronicFenceEditVo.getGeofence_type() == 3) {
+            //围栏-行政区划围栏
+            gfid = trackGeofenceUpdateDistrict(tElectronicFenceEditVo, tElectronicFenceKey, fenceService, tElectronicFence);
+        } else {
+            log.error("更新围栏禁止围栏类型为不匹配,id:{}.", tElectronicFenceEditVo.getId());
+            throw new ServiceException("更新围栏禁止围栏类型为不匹配!");
+        }
+        //更新围栏失败
+        if (gfid == null || StringUtils.isEmpty(gfid)) {
+            log.error("更新围栏失败,id:{}.", tElectronicFenceEditVo.getId());
+            throw new ServiceException("更新围栏失败!");
+        }
+        //围栏的唯一标识
+        fence.setGfid(gfid);
+        //围栏服务ID
+        fence.setServiceId(fenceService.getId());
+        //更新时间
+        fence.setUpdateTime(DateUtils.getNowDate());
+        return tElectronicFenceMapper.updateTElectronicFence(fence);
+    }
+
+
+    /**
+     * 创建围栏-圆形
+     */
+    private int trackGeofenceAddCircle(ElectronicFenceVo fenceVo) {
+        //获取所有高德Key
+        TElectronicFenceKey electronicFenceKey = iElectronicFenceKeyService.selectAccessAvailableElectronicFenceKey();
+        if (electronicFenceKey == null) {
+            log.error("获取高德所有amap_key为空.");
+            throw new ServiceException("获取所有高德amap_key为空!");
+        }
+        //通过key查询service(每个 Key 下最多注册15个 Service)
+        TElectronicFenceService electronicFenceService = iElectronicFenceServiceService.selectAccessAvailableElectronicFenceServiceByKeyId(electronicFenceKey.getId());
+        if (electronicFenceService == null) {
+            log.error("获取高德所有amap_service为空,key:{}", electronicFenceKey.getAmapKey());
+            throw new ServiceException("获取所有高德amap_service为空!");
+        }
+        //通过service创建围栏(一个service下最多可创建1000个围栏)
+        String gfid = sendGeoAddCircle(electronicFenceKey, electronicFenceService, fenceVo);
+        if (StringUtils.isEmpty(gfid)) {
+            log.error("创建高德围栏异常!");
+            throw new ServiceException("创建高德围栏异常!");
+        }
+        //存储围栏信息
+        TElectronicFence tElectronicFence = new TElectronicFence();
+        tElectronicFence.setName(fenceVo.getName());
+        tElectronicFence.setStartTime(new Date(fenceVo.getStart_time()));
+        tElectronicFence.setEndTime(new Date(fenceVo.getEnd_time()));
+        tElectronicFence.seteState(fenceVo.getState());
+        tElectronicFence.seteType(fenceVo.getType());
+        tElectronicFence.setGfid(gfid);
+        tElectronicFence.setUserId(fenceVo.getUsdId());
+        tElectronicFence.setDeviceId(fenceVo.getDeviceId());
+        tElectronicFence.setServiceId(electronicFenceService.getId());
+        tElectronicFence.setCreateTime(DateUtils.getNowDate());
+        return tElectronicFenceMapper.insertTElectronicFence(tElectronicFence);
+    }
+
+    /**
+     * 创建围栏-多边形围栏
+     */
+    private int trackGeofenceAddPolygon(ElectronicFenceVo fenceVo) {
+        //获取所有高德Key
+        TElectronicFenceKey electronicFenceKey = iElectronicFenceKeyService.selectAccessAvailableElectronicFenceKey();
+        if (electronicFenceKey == null) {
+            log.error("获取高德所有amap_key为空.");
+            throw new ServiceException("获取所有高德amap_key为空!");
+        }
+        //通过key查询service(每个 Key 下最多注册15个 Service)
+        TElectronicFenceService electronicFenceService = iElectronicFenceServiceService.selectAccessAvailableElectronicFenceServiceByKeyId(electronicFenceKey.getId());
+        if (electronicFenceService == null) {
+            log.error("获取高德所有amap_service为空,key:{}", electronicFenceKey.getAmapKey());
+            throw new ServiceException("获取所有高德amap_service为空!");
+        }
+        //通过service创建围栏(一个service下最多可创建1000个围栏)
+        String gfid = sendGeoAddPolygon(electronicFenceKey, electronicFenceService, fenceVo);
+        if (StringUtils.isEmpty(gfid)) {
+            log.error("创建高德围栏异常!");
+            throw new ServiceException("创建高德围栏异常!");
+        }
+        //存储围栏信息
+        TElectronicFence tElectronicFence = new TElectronicFence();
+        tElectronicFence.setName(fenceVo.getName());
+        tElectronicFence.setStartTime(new Date(fenceVo.getStart_time()));
+        tElectronicFence.setEndTime(new Date(fenceVo.getEnd_time()));
+        tElectronicFence.seteState(fenceVo.getState());
+        tElectronicFence.seteType(fenceVo.getType());
+        tElectronicFence.setGfid(gfid);
+        tElectronicFence.setUserId(fenceVo.getUsdId());
+        tElectronicFence.setDeviceId(fenceVo.getDeviceId());
+        tElectronicFence.setServiceId(electronicFenceService.getId());
+        tElectronicFence.setCreateTime(DateUtils.getNowDate());
+        return tElectronicFenceMapper.insertTElectronicFence(tElectronicFence);
+    }
+
+    /**
+     * 创建围栏-线形围栏
+     */
+    private int trackGeofenceAddPolyline(ElectronicFenceVo fenceVo) {
+        //获取所有高德Key
+        TElectronicFenceKey electronicFenceKey = iElectronicFenceKeyService.selectAccessAvailableElectronicFenceKey();
+        if (electronicFenceKey == null) {
+            log.error("获取高德所有amap_key为空.");
+            throw new ServiceException("获取所有高德amap_key为空!");
+        }
+        //通过key查询service(每个 Key 下最多注册15个 Service)
+        TElectronicFenceService electronicFenceService = iElectronicFenceServiceService.selectAccessAvailableElectronicFenceServiceByKeyId(electronicFenceKey.getId());
+        if (electronicFenceService == null) {
+            log.error("获取高德所有amap_service为空,key:{}", electronicFenceKey.getAmapKey());
+            throw new ServiceException("获取所有高德amap_service为空!");
+        }
+        //通过service创建围栏(一个service下最多可创建1000个围栏)
+        String gfid = sendGeoAddPolyline(electronicFenceKey, electronicFenceService, fenceVo);
+        if (StringUtils.isEmpty(gfid)) {
+            log.error("创建高德围栏异常!");
+            throw new ServiceException("创建高德围栏异常!");
+        }
+        //存储围栏信息
+        TElectronicFence tElectronicFence = new TElectronicFence();
+        tElectronicFence.setName(fenceVo.getName());
+        tElectronicFence.setStartTime(new Date(fenceVo.getStart_time()));
+        tElectronicFence.setEndTime(new Date(fenceVo.getEnd_time()));
+        tElectronicFence.seteState(fenceVo.getState());
+        tElectronicFence.seteType(fenceVo.getType());
+        tElectronicFence.setGfid(gfid);
+        tElectronicFence.setUserId(fenceVo.getUsdId());
+        tElectronicFence.setDeviceId(fenceVo.getDeviceId());
+        tElectronicFence.setServiceId(electronicFenceService.getId());
+        tElectronicFence.setCreateTime(DateUtils.getNowDate());
+        return tElectronicFenceMapper.insertTElectronicFence(tElectronicFence);
+    }
+
+    /**
+     * 创建围栏-行政区划围栏
+     */
+    private int trackGeofenceAddDistrict(ElectronicFenceVo fenceVo) {
+        //获取所有高德Key
+        TElectronicFenceKey electronicFenceKey = iElectronicFenceKeyService.selectAccessAvailableElectronicFenceKey();
+        if (electronicFenceKey == null) {
+            log.error("获取高德所有amap_key为空.");
+            throw new ServiceException("获取所有高德amap_key为空!");
+        }
+        //通过key查询service(每个 Key 下最多注册15个 Service)
+        TElectronicFenceService electronicFenceService = iElectronicFenceServiceService.selectAccessAvailableElectronicFenceServiceByKeyId(electronicFenceKey.getId());
+        if (electronicFenceService == null) {
+            log.error("获取高德所有amap_service为空,key:{}", electronicFenceKey.getAmapKey());
+            throw new ServiceException("获取所有高德amap_service为空!");
+        }
+        //通过service创建围栏(一个service下最多可创建1000个围栏)
+        String gfid = sendGeoAddDistrict(electronicFenceKey, electronicFenceService, fenceVo);
+        if (StringUtils.isEmpty(gfid)) {
+            log.error("创建高德围栏异常!");
+            throw new ServiceException("创建高德围栏异常!");
+        }
+        //存储围栏信息
+        TElectronicFence tElectronicFence = new TElectronicFence();
+        tElectronicFence.setName(fenceVo.getName());
+        tElectronicFence.setStartTime(new Date(fenceVo.getStart_time()));
+        tElectronicFence.setEndTime(new Date(fenceVo.getEnd_time()));
+        tElectronicFence.seteState(fenceVo.getState());
+        tElectronicFence.seteType(fenceVo.getType());
+        tElectronicFence.setGfid(gfid);
+        tElectronicFence.setUserId(fenceVo.getUsdId());
+        tElectronicFence.setDeviceId(fenceVo.getDeviceId());
+        tElectronicFence.setServiceId(electronicFenceService.getId());
+        tElectronicFence.setCreateTime(DateUtils.getNowDate());
+        return tElectronicFenceMapper.insertTElectronicFence(tElectronicFence);
+    }
+
+    /**
+     * 通过高德接口创建圆形围栏
+     *
+     * @param fenceKey
+     * @param fenceService
+     * @param fenceVo
+     * @return
+     */
+    private String sendGeoAddCircle(TElectronicFenceKey fenceKey, TElectronicFenceService fenceService, ElectronicFenceVo fenceVo) {
+        //创建圆形围栏
+        Map<Object, Object> params = new HashMap();
+        params.put("key", fenceKey.getAmapKey());
+        params.put("sid", fenceService.getAmapSid());
+        params.put("name", fenceVo.getName());
+        if (!StringUtils.isEmpty(fenceVo.getDesc())) {
+            params.put("desc", fenceVo.getDesc());
+        }
+        params.put("center", fenceVo.getCenter());
+        params.put("radius", fenceVo.getRadius());
+        String paramsString = HttpUtils.getParamsToString(params);
+        // 去掉最后一个"&"符号
+        String result = HttpUtils.sendPost(AMapConstants.AMAP_GEOFENCE_ADD_CIRCLE, paramsString);
+        log.info("创建高德围栏Url:{} ,\n返回结果:{}", AMapConstants.AMAP_GEOFENCE_ADD_CIRCLE + "?" + paramsString, result);
+        AMapResult<Map<String, String>> aMapResult = JSONObject.parseObject(result, AMapResult.class);
+        if (aMapResult != null && aMapResult.getData() != null && aMapResult.getData().containsKey("gfid")) {
+            return String.valueOf(aMapResult.getData().get("gfid"));
+        }
+        log.info("创建高德围栏异常,key:{} ,code:{} ,msg:{}", fenceKey.getAmapKey(), aMapResult.getErrmsg(), aMapResult.getErrdetail());
+        throw new ServiceException("创建高德围栏异常,msg:" + aMapResult.getErrdetail() + " !");
+    }
+
+    /**
+     * 通过高德接口创建多边形围栏
+     *
+     * @param fenceKey
+     * @param fenceService
+     * @param fenceVo
+     * @return
+     */
+    private String sendGeoAddPolygon(TElectronicFenceKey fenceKey, TElectronicFenceService fenceService, ElectronicFenceVo fenceVo) {
+        //创建圆形围栏
+        Map<Object, Object> params = new HashMap();
+        params.put("key", fenceKey.getAmapKey());
+        params.put("sid", fenceService.getAmapSid());
+        params.put("name", fenceVo.getName());
+        if (!StringUtils.isEmpty(fenceVo.getDesc())) {
+            params.put("desc", fenceVo.getDesc());
+        }
+        params.put("points", fenceVo.getPoints());
+        String paramsString = HttpUtils.getParamsToString(params);
+        // 去掉最后一个"&"符号
+        String result = HttpUtils.sendPost(AMapConstants.AMAP_GEOFENCE_ADD_POLYGON, paramsString);
+        log.info("创建高德围栏Url:{} ,\n返回结果:{}", AMapConstants.AMAP_GEOFENCE_ADD_POLYGON + "?" + paramsString, result);
+        AMapResult<Map<String, String>> aMapResult = JSONObject.parseObject(result, AMapResult.class);
+        if (aMapResult != null && aMapResult.getData() != null && aMapResult.getData().containsKey("gfid")) {
+            return String.valueOf(aMapResult.getData().get("gfid"));
+        }
+        log.info("创建高德围栏异常,key:{} ,code:{} ,msg:{}", fenceKey.getAmapKey(), aMapResult.getErrmsg(), aMapResult.getErrdetail());
+        throw new ServiceException("创建高德围栏异常,msg:" + aMapResult.getErrdetail() + " !");
+    }
+
+    /**
+     * 通过高德接口创建线形围栏
+     *
+     * @param fenceKey
+     * @param fenceService
+     * @param fenceVo
+     * @return
+     */
+    private String sendGeoAddPolyline(TElectronicFenceKey fenceKey, TElectronicFenceService fenceService, ElectronicFenceVo fenceVo) {
+        //创建圆形围栏
+        Map<Object, Object> params = new HashMap();
+        params.put("key", fenceKey.getAmapKey());
+        params.put("sid", fenceService.getAmapSid());
+        params.put("name", fenceVo.getName());
+        if (!StringUtils.isEmpty(fenceVo.getDesc())) {
+            params.put("desc", fenceVo.getDesc());
+        }
+        params.put("points", fenceVo.getCenter());
+        params.put("bufferradius", fenceVo.getBufferradius());
+        String paramsString = HttpUtils.getParamsToString(params);
+        // 去掉最后一个"&"符号
+        String result = HttpUtils.sendPost(AMapConstants.AMAP_GEOFENCE_ADD_POLYLINE, paramsString);
+        log.info("创建高德围栏Url:{} ,\n返回结果:{}", AMapConstants.AMAP_GEOFENCE_ADD_POLYLINE + "?" + paramsString, result);
+        AMapResult<Map<String, String>> aMapResult = JSONObject.parseObject(result, AMapResult.class);
+        if (aMapResult != null && aMapResult.getData() != null && aMapResult.getData().containsKey("gfid")) {
+            return String.valueOf(aMapResult.getData().get("gfid"));
+        }
+        log.info("创建高德围栏异常,key:{} ,code:{} ,msg:{}", fenceKey.getAmapKey(), aMapResult.getErrmsg(), aMapResult.getErrdetail());
+        throw new ServiceException("创建高德围栏异常,msg:" + aMapResult.getErrdetail() + " !");
+    }
+
+    /**
+     * 通过高德接口创建行政区划围栏
+     *
+     * @param fenceKey
+     * @param fenceService
+     * @param fenceVo
+     * @return
+     */
+    private String sendGeoAddDistrict(TElectronicFenceKey fenceKey, TElectronicFenceService fenceService, ElectronicFenceVo fenceVo) {
+        //创建圆形围栏
+        Map<Object, Object> params = new HashMap();
+        params.put("key", fenceKey.getAmapKey());
+        params.put("sid", fenceService.getAmapSid());
+        params.put("name", fenceVo.getName());
+        if (!StringUtils.isEmpty(fenceVo.getDesc())) {
+            params.put("desc", fenceVo.getDesc());
+        }
+        params.put("adcode", fenceVo.getAdcode());
+        String paramsString = HttpUtils.getParamsToString(params);
+        // 去掉最后一个"&"符号
+        String result = HttpUtils.sendPost(AMapConstants.AMAP_GEOFENCE_ADD_DISTRICT, paramsString);
+        log.info("创建高德围栏Url:{} ,\n返回结果:{}", AMapConstants.AMAP_GEOFENCE_ADD_DISTRICT + "?" + paramsString, result);
+        AMapResult<Map<String, String>> aMapResult = JSONObject.parseObject(result, AMapResult.class);
+        if (aMapResult != null && aMapResult.getData() != null && aMapResult.getData().containsKey("gfid")) {
+            return String.valueOf(aMapResult.getData().get("gfid"));
+        }
+        log.info("创建高德围栏异常,key:{} ,code:{} ,msg:{}", fenceKey.getAmapKey(), aMapResult.getErrmsg(), aMapResult.getErrdetail());
+        throw new ServiceException("创建高德围栏异常,msg:" + aMapResult.getErrdetail() + " !");
+    }
+
+    /**
+     * 通过高德接口删除围栏
+     *
+     * @param fenceKey
+     * @param fenceService
+     * @param gfids
+     * @return
+     */
+    private String sendGeoDel(TElectronicFenceKey fenceKey, TElectronicFenceService fenceService, String gfids) {
+        //创建圆形围栏
+        Map<Object, Object> params = new HashMap();
+        params.put("key", fenceKey.getAmapKey());
+        params.put("sid", fenceService.getAmapSid());
+        params.put("gfids", gfids);
+        String paramsString = HttpUtils.getParamsToString(params);
+        // 去掉最后一个"&"符号
+        String result = HttpUtils.sendPost(AMapConstants.AMAP_TRACK_SERVICE_DELETE, paramsString);
+        log.info("删除高德围栏Url:{} ,\n返回结果:{}", AMapConstants.AMAP_TRACK_SERVICE_DELETE + "?" + paramsString, result);
+        AMapResult<Map<String, String>> aMapResult = JSONObject.parseObject(result, AMapResult.class);
+        if (aMapResult != null && aMapResult.getData() != null && aMapResult.getData().containsKey("gfids")) {
+            return String.valueOf(aMapResult.getData().get("gfids"));
+        }
+        log.info("删除高德围栏异常,key:{},gfids:{} ,code:{} ,msg:{}", fenceKey.getAmapKey(), gfids, aMapResult.getErrmsg(), aMapResult.getErrdetail());
+        throw new ServiceException("删除高德围栏异常,msg:" + aMapResult.getErrdetail() + " !");
+    }
+
+    /**
+     * 更新围栏-圆形
+     *
+     * @param fenceVo
+     * @param fenceKey
+     * @param fenceService
+     * @param tElectronicFence
+     * @return
+     */
+    private String trackGeofenceUpdateCircle(ElectronicFenceVo fenceVo, TElectronicFenceKey fenceKey, TElectronicFenceService fenceService, TElectronicFence tElectronicFence) {
+        //更新圆形围栏
+        AMapUpdateCircleTo aMapUpdateCircleTo = new AMapUpdateCircleTo();
+        BeanUtils.copyBeanProp(aMapUpdateCircleTo, fenceVo);
+        aMapUpdateCircleTo.setKey(fenceKey.getAmapKey());
+        aMapUpdateCircleTo.setSid(fenceService.getAmapSid());
+        aMapUpdateCircleTo.setGfid(tElectronicFence.getGfid());
+        //围栏昵称
+        if (!StringUtils.isEmpty(aMapUpdateCircleTo.getName())) {
+            //修改围栏昵称
+            aMapUpdateCircleTo.setName(aMapUpdateCircleTo.getName());
+        } else {
+            //不修改围栏昵称
+            aMapUpdateCircleTo.setName(tElectronicFence.getName());
+        }
+        //围栏描述
+        if (!StringUtils.isEmpty(aMapUpdateCircleTo.getDesc())) {
+            //修改围栏描述
+            aMapUpdateCircleTo.setDesc(aMapUpdateCircleTo.getDesc());
+        } else {
+            //不修改围栏描述
+            aMapUpdateCircleTo.setDesc(tElectronicFence.geteDesc());
+        }
+        //围栏中心点坐标 格式X,Y 必填
+        if (!StringUtils.isEmpty(aMapUpdateCircleTo.getCenter())) {
+            //修改围栏中心点坐标
+            aMapUpdateCircleTo.setCenter(aMapUpdateCircleTo.getCenter());
+        } else {
+            log.error("围栏中心点坐标禁止为空,gfid:{}.", tElectronicFence.getGfid());
+            throw new ServiceException("更新围栏禁止围栏中心点坐标为空!");
+        }
+        //围栏半径 单位:米,整数,取值范[1,50000] 必填
+        if (!StringUtils.isEmpty(aMapUpdateCircleTo.getRadius())) {
+            //修改围栏半径
+            aMapUpdateCircleTo.setRadius(aMapUpdateCircleTo.getRadius());
+        } else {
+            log.error("围栏半径禁止为空,gfid:{}.", tElectronicFence.getGfid());
+            throw new ServiceException("更新围栏禁止围栏半径为空!");
+        }
+        return sendGeoUpdateCircle(aMapUpdateCircleTo);
+    }
+
+    /**
+     * 更新围栏-多边形围栏
+     */
+    private String trackGeofenceUpdatePolygon(ElectronicFenceVo fenceVo, TElectronicFenceKey fenceKey, TElectronicFenceService fenceService, TElectronicFence tElectronicFence) {
+        //更新多边形围栏
+        AMapUpdatePolygonTo aMapUpdatePolygonTo = new AMapUpdatePolygonTo();
+        BeanUtils.copyBeanProp(aMapUpdatePolygonTo, fenceVo);
+        aMapUpdatePolygonTo.setKey(fenceKey.getAmapKey());
+        aMapUpdatePolygonTo.setSid(fenceService.getAmapSid());
+        aMapUpdatePolygonTo.setGfid(tElectronicFence.getGfid());
+        //围栏昵称
+        if (!StringUtils.isEmpty(aMapUpdatePolygonTo.getName())) {
+            //修改围栏昵称
+            aMapUpdatePolygonTo.setName(aMapUpdatePolygonTo.getName());
+        } else {
+            //不修改围栏昵称
+            aMapUpdatePolygonTo.setName(tElectronicFence.getName());
+        }
+        //围栏描述
+        if (!StringUtils.isEmpty(aMapUpdatePolygonTo.getDesc())) {
+            //修改围栏描述
+            aMapUpdatePolygonTo.setDesc(aMapUpdatePolygonTo.getDesc());
+        } else {
+            //不修改围栏描述
+            aMapUpdatePolygonTo.setDesc(tElectronicFence.geteDesc());
+        }
+        //多边形顶点坐标 格式 X1,Y1;X2,Y2 必填
+        if (!StringUtils.isEmpty(aMapUpdatePolygonTo.getPoints())) {
+            //修改围栏多边形顶点坐标
+            aMapUpdatePolygonTo.setPoints(aMapUpdatePolygonTo.getPoints());
+        } else {
+            log.error("围栏多边形顶点坐标禁止为空,gfid:{}.", tElectronicFence.getGfid());
+            throw new ServiceException("更新围栏禁止多边形顶点坐标为空!");
+        }
+        return sendGeoUpdatePolygon(aMapUpdatePolygonTo);
+    }
+
+    /**
+     * 更新围栏-线形围栏
+     */
+    private String trackGeofenceUpdatePolyline(ElectronicFenceVo fenceVo, TElectronicFenceKey fenceKey, TElectronicFenceService fenceService, TElectronicFence tElectronicFence) {
+        //更新线形围栏
+        AMapUpdatePolyLineTo aMapUpdatePolyLineTo = new AMapUpdatePolyLineTo();
+        BeanUtils.copyBeanProp(aMapUpdatePolyLineTo, fenceVo);
+        aMapUpdatePolyLineTo.setKey(fenceKey.getAmapKey());
+        aMapUpdatePolyLineTo.setSid(fenceService.getAmapSid());
+        aMapUpdatePolyLineTo.setGfid(tElectronicFence.getGfid());
+        //围栏昵称
+        if (!StringUtils.isEmpty(aMapUpdatePolyLineTo.getName())) {
+            //修改围栏昵称
+            aMapUpdatePolyLineTo.setName(aMapUpdatePolyLineTo.getName());
+        } else {
+            //不修改围栏昵称
+            aMapUpdatePolyLineTo.setName(tElectronicFence.getName());
+        }
+        //围栏描述
+        if (!StringUtils.isEmpty(aMapUpdatePolyLineTo.getDesc())) {
+            //修改围栏描述
+            aMapUpdatePolyLineTo.setDesc(aMapUpdatePolyLineTo.getDesc());
+        } else {
+            //不修改围栏描述
+            aMapUpdatePolyLineTo.setDesc(tElectronicFence.geteDesc());
+        }
+        //多边形顶点坐标 格式 X1,Y1;X2,Y2 必填
+        if (!StringUtils.isEmpty(aMapUpdatePolyLineTo.getPoints())) {
+            //修改围栏多边形顶点坐标
+            aMapUpdatePolyLineTo.setPoints(aMapUpdatePolyLineTo.getPoints());
+        } else {
+            log.error("围栏线形顶点坐标禁止为空,gfid:{}.", tElectronicFence.getGfid());
+            throw new ServiceException("更新围栏禁止线形点坐标为空!");
+        }
+        //沿线偏移距离 单位:米 取值范围 [1,300]
+        if (!StringUtils.isEmpty(aMapUpdatePolyLineTo.getBufferradius())) {
+            //修改围栏多边形顶点坐标
+            aMapUpdatePolyLineTo.setBufferradius(aMapUpdatePolyLineTo.getBufferradius());
+        } else {
+            log.error("围栏线形沿线偏移距离禁止为空,gfid:{}.", tElectronicFence.getGfid());
+            throw new ServiceException("更新围栏禁止线形沿线偏移距离为空!");
+        }
+        return sendGeoUpdatePolyline(aMapUpdatePolyLineTo);
+    }
+
+    /**
+     * 更新围栏-行政区划围栏
+     */
+    private String trackGeofenceUpdateDistrict(ElectronicFenceVo fenceVo, TElectronicFenceKey fenceKey, TElectronicFenceService fenceService, TElectronicFence tElectronicFence) {
+        //更新行政区划围栏
+        AMapUpdateDistrictTo aMapUpdateDistrictTo = new AMapUpdateDistrictTo();
+        BeanUtils.copyBeanProp(aMapUpdateDistrictTo, fenceVo);
+        aMapUpdateDistrictTo.setKey(fenceKey.getAmapKey());
+        aMapUpdateDistrictTo.setSid(fenceService.getAmapSid());
+        aMapUpdateDistrictTo.setGfid(tElectronicFence.getGfid());
+        //围栏昵称
+        if (!StringUtils.isEmpty(aMapUpdateDistrictTo.getName())) {
+            //修改围栏昵称
+            aMapUpdateDistrictTo.setName(aMapUpdateDistrictTo.getName());
+        } else {
+            //不修改围栏昵称
+            aMapUpdateDistrictTo.setName(tElectronicFence.getName());
+        }
+        //围栏描述
+        if (!StringUtils.isEmpty(aMapUpdateDistrictTo.getDesc())) {
+            //修改围栏描述
+            aMapUpdateDistrictTo.setDesc(aMapUpdateDistrictTo.getDesc());
+        } else {
+            //不修改围栏描述
+            aMapUpdateDistrictTo.setDesc(tElectronicFence.geteDesc());
+        }
+        //行政区划编码 参考行政区划编码表 必填
+        if (!StringUtils.isEmpty(aMapUpdateDistrictTo.getAdcode())) {
+            //修改围栏多边形顶点坐标
+            aMapUpdateDistrictTo.setAdcode(aMapUpdateDistrictTo.getAdcode());
+        } else {
+            log.error("围栏行政区划行政区划编码禁止为空,gfid:{}.", tElectronicFence.getGfid());
+            throw new ServiceException("更新围栏禁止行政区划行政区划编码为空!");
+        }
+        return sendGeoUpdateDistrict(aMapUpdateDistrictTo);
+    }
+
+    /**
+     * 通过高德接口更新圆形围栏
+     *
+     * @param aMapUpdateCircleTo
+     * @return
+     */
+    private String sendGeoUpdateCircle(@Validated AMapUpdateCircleTo aMapUpdateCircleTo) {
+        //更新圆形围栏
+        Map<Object, Object> params = new HashMap();
+        params.put("key", aMapUpdateCircleTo.getKey());
+        params.put("sid", aMapUpdateCircleTo.getSid());
+        params.put("gfid", aMapUpdateCircleTo.getGfid());
+        params.put("name", aMapUpdateCircleTo.getName());
+        if (!StringUtils.isEmpty(aMapUpdateCircleTo.getDesc())) {
+            params.put("desc", aMapUpdateCircleTo.getDesc());
+        }
+        params.put("center", aMapUpdateCircleTo.getCenter());
+        params.put("radius", aMapUpdateCircleTo.getRadius());
+        String paramsString = HttpUtils.getParamsToString(params);
+        // 去掉最后一个"&"符号
+        String result = HttpUtils.sendPost(AMapConstants.AMAP_GEOFENCE_UPDATE_CIRCLE, paramsString);
+        log.info("更新高德围栏Url:{} ,\n返回结果:{}", AMapConstants.AMAP_GEOFENCE_UPDATE_CIRCLE + "?" + paramsString, result);
+        AMapResult aMapResult = JSONObject.parseObject(result, AMapResult.class);
+        if (aMapResult != null && aMapResult.getErrcode() == 10000) {
+            return aMapUpdateCircleTo.getGfid();
+        }
+        log.info("更新高德围栏异常,key:{} ,code:{} ,msg:{}", aMapUpdateCircleTo.getKey(), aMapResult.getErrmsg(), aMapResult.getErrdetail());
+        throw new ServiceException("更新高德围栏异常,msg:" + aMapResult.getErrdetail() + " !");
+    }
+
+    /**
+     * 通过高德接口更新多边形围栏
+     *
+     * @param aMapUpdatePolygonTo
+     * @return
+     */
+    private String sendGeoUpdatePolygon(@Validated AMapUpdatePolygonTo aMapUpdatePolygonTo) {
+        //更新多边形围栏
+        Map<Object, Object> params = new HashMap();
+        params.put("key", aMapUpdatePolygonTo.getKey());
+        params.put("sid", aMapUpdatePolygonTo.getSid());
+        params.put("gfid", aMapUpdatePolygonTo.getGfid());
+        params.put("name", aMapUpdatePolygonTo.getName());
+        if (!StringUtils.isEmpty(aMapUpdatePolygonTo.getDesc())) {
+            params.put("desc", aMapUpdatePolygonTo.getDesc());
+        }
+        params.put("points", aMapUpdatePolygonTo.getPoints());
+        String paramsString = HttpUtils.getParamsToString(params);
+        // 去掉最后一个"&"符号
+        String result = HttpUtils.sendPost(AMapConstants.AMAP_GEOFENCE_UPDATE_POLYGON, paramsString);
+        log.info("更新高德围栏Url:{} ,\n返回结果:{}", AMapConstants.AMAP_GEOFENCE_UPDATE_POLYGON + "?" + paramsString, result);
+        AMapResult aMapResult = JSONObject.parseObject(result, AMapResult.class);
+        if (aMapResult != null && aMapResult.getErrcode() == 10000) {
+            return aMapUpdatePolygonTo.getGfid();
+        }
+        log.info("更新高德围栏异常,key:{} ,code:{} ,msg:{}", aMapUpdatePolygonTo.getKey(), aMapResult.getErrmsg(), aMapResult.getErrdetail());
+        throw new ServiceException("更新高德围栏异常,msg:" + aMapResult.getErrdetail() + " !");
+    }
+
+    /**
+     * 通过高德接口更新线形围栏
+     *
+     * @param aMapUpdatePolyLineTo
+     * @return
+     */
+    private String sendGeoUpdatePolyline(@Validated AMapUpdatePolyLineTo aMapUpdatePolyLineTo) {
+        //更新多边形围栏
+        Map<Object, Object> params = new HashMap();
+        params.put("key", aMapUpdatePolyLineTo.getKey());
+        params.put("sid", aMapUpdatePolyLineTo.getSid());
+        params.put("gfid", aMapUpdatePolyLineTo.getGfid());
+        params.put("name", aMapUpdatePolyLineTo.getName());
+        if (!StringUtils.isEmpty(aMapUpdatePolyLineTo.getDesc())) {
+            params.put("desc", aMapUpdatePolyLineTo.getDesc());
+        }
+        params.put("points", aMapUpdatePolyLineTo.getPoints());
+        params.put("bufferradius", aMapUpdatePolyLineTo.getBufferradius());
+        String paramsString = HttpUtils.getParamsToString(params);
+        // 去掉最后一个"&"符号
+        String result = HttpUtils.sendPost(AMapConstants.AMAP_GEOFENCE_UPDATE_POLYLINE, paramsString);
+        log.info("更新高德围栏Url:{} ,\n返回结果:{}", AMapConstants.AMAP_GEOFENCE_UPDATE_POLYLINE + "?" + paramsString, result);
+        AMapResult aMapResult = JSONObject.parseObject(result, AMapResult.class);
+        if (aMapResult != null && aMapResult.getErrcode() == 10000) {
+            return aMapUpdatePolyLineTo.getGfid();
+        }
+        log.info("更新高德围栏异常,key:{} ,code:{} ,msg:{}", aMapUpdatePolyLineTo.getKey(), aMapResult.getErrmsg(), aMapResult.getErrdetail());
+        throw new ServiceException("更新高德围栏异常,msg:" + aMapResult.getErrdetail() + " !");
+    }
+
+    /**
+     * 通过高德接口更新行政区划围栏
+     *
+     * @param aMapUpdateDistrictTo
+     * @return
+     */
+    private String sendGeoUpdateDistrict(@Validated AMapUpdateDistrictTo aMapUpdateDistrictTo) {
+        //更新多边形围栏
+        Map<Object, Object> params = new HashMap();
+        params.put("key", aMapUpdateDistrictTo.getKey());
+        params.put("sid", aMapUpdateDistrictTo.getSid());
+        params.put("gfid", aMapUpdateDistrictTo.getGfid());
+        params.put("name", aMapUpdateDistrictTo.getName());
+        if (!StringUtils.isEmpty(aMapUpdateDistrictTo.getDesc())) {
+            params.put("desc", aMapUpdateDistrictTo.getDesc());
+        }
+        params.put("adcode", aMapUpdateDistrictTo.getAdcode());
+        String paramsString = HttpUtils.getParamsToString(params);
+        // 去掉最后一个"&"符号
+        String result = HttpUtils.sendPost(AMapConstants.AMAP_GEOFENCE_UPDATE_DISTRICT, paramsString);
+        log.info("更新高德围栏Url:{} ,\n返回结果:{}", AMapConstants.AMAP_GEOFENCE_UPDATE_DISTRICT + "?" + paramsString, result);
+        AMapResult aMapResult = JSONObject.parseObject(result, AMapResult.class);
+        if (aMapResult != null && aMapResult.getErrcode() == 10000) {
+            return aMapUpdateDistrictTo.getGfid();
+        }
+        log.info("更新高德围栏异常,key:{} ,code:{} ,msg:{}", aMapUpdateDistrictTo.getKey(), aMapResult.getErrmsg(), aMapResult.getErrdetail());
+        throw new ServiceException("更新高德围栏异常,msg:" + aMapResult.getErrdetail() + " !");
+    }
+}

+ 116 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TElectronicFenceServiceServiceImpl.java

@@ -0,0 +1,116 @@
+package com.ruoyi.system.service.impl;
+
+import java.util.List;
+
+import com.alibaba.fastjson.JSONObject;
+import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.system.domain.TElectronicFenceKey;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.system.mapper.TElectronicFenceServiceMapper;
+import com.ruoyi.system.domain.TElectronicFenceService;
+import com.ruoyi.system.service.ITElectronicFenceServiceService;
+
+/**
+ * 【请填写功能名称】Service业务层处理
+ *
+ * @author ruoyi
+ * @date 2023-09-14
+ */
+@Service
+public class TElectronicFenceServiceServiceImpl implements ITElectronicFenceServiceService {
+
+    private static final Logger log = LoggerFactory.getLogger(TElectronicFenceServiceServiceImpl.class);
+    @Autowired
+    private TElectronicFenceServiceMapper tElectronicFenceServiceMapper;
+
+    /**
+     * 查询【请填写功能名称】
+     *
+     * @param id 【请填写功能名称】主键
+     * @return 【请填写功能名称】
+     */
+    @Override
+    public TElectronicFenceService selectTElectronicFenceServiceById(Long id) {
+        return tElectronicFenceServiceMapper.selectTElectronicFenceServiceById(id);
+    }
+
+    /**
+     * 查询【请填写功能名称】列表
+     *
+     * @param tElectronicFenceService 【请填写功能名称】
+     * @return 【请填写功能名称】
+     */
+    @Override
+    public List<TElectronicFenceService> selectTElectronicFenceServiceList(TElectronicFenceService tElectronicFenceService) {
+        return tElectronicFenceServiceMapper.selectTElectronicFenceServiceList(tElectronicFenceService);
+    }
+
+    /**
+     * 新增【请填写功能名称】
+     *
+     * @param tElectronicFenceService 【请填写功能名称】
+     * @return 结果
+     */
+    @Override
+    public int insertTElectronicFenceService(TElectronicFenceService tElectronicFenceService) {
+        tElectronicFenceService.setCreateTime(DateUtils.getNowDate());
+        return tElectronicFenceServiceMapper.insertTElectronicFenceService(tElectronicFenceService);
+    }
+
+    /**
+     * 修改【请填写功能名称】
+     *
+     * @param tElectronicFenceService 【请填写功能名称】
+     * @return 结果
+     */
+    @Override
+    public int updateTElectronicFenceService(TElectronicFenceService tElectronicFenceService) {
+        tElectronicFenceService.setUpdateTime(DateUtils.getNowDate());
+        return tElectronicFenceServiceMapper.updateTElectronicFenceService(tElectronicFenceService);
+    }
+
+    /**
+     * 批量删除【请填写功能名称】
+     *
+     * @param ids 需要删除的【请填写功能名称】主键
+     * @return 结果
+     */
+    @Override
+    public int deleteTElectronicFenceServiceByIds(Long[] ids) {
+        return tElectronicFenceServiceMapper.deleteTElectronicFenceServiceByIds(ids);
+    }
+
+    /**
+     * 删除【请填写功能名称】信息
+     *
+     * @param id 【请填写功能名称】主键
+     * @return 结果
+     */
+    @Override
+    public int deleteTElectronicFenceServiceById(Long id) {
+        return tElectronicFenceServiceMapper.deleteTElectronicFenceServiceById(id);
+    }
+
+    @Override
+    public List<TElectronicFenceService> selectTElectronicFenceServiceByKeyId(Long keyId) {
+        return tElectronicFenceServiceMapper.selectTElectronicFenceServiceByKeyId(keyId);
+    }
+
+    @Override
+    public TElectronicFenceService selectAccessAvailableElectronicFenceServiceByKeyId(Long keyId) {
+        //获取所有的Key
+        List<TElectronicFenceService> electronicFenceServices = tElectronicFenceServiceMapper.selectTElectronicFenceServiceByKeyId(keyId);
+        if (electronicFenceServices != null && !electronicFenceServices.isEmpty()) {
+            log.info("获取高德所有amap_service:{} .", JSONObject.toJSONString(electronicFenceServices));
+            return electronicFenceServices.get(0);
+        } else {
+            log.error("获取高德所有amap_service为空,去创建!");
+            //TODO 根据key创建高德服务
+
+        }
+        return null;
+    }
+}

+ 107 - 0
ruoyi-system/src/main/java/com/ruoyi/system/timing/GeofenceDeleteTiming.java

@@ -0,0 +1,107 @@
+package com.ruoyi.system.timing;
+
+import com.alibaba.fastjson.JSONObject;
+import com.ruoyi.common.constant.AMapConstants;
+import com.ruoyi.common.core.domain.AMapResult;
+import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.common.utils.http.HttpUtils;
+import com.ruoyi.system.domain.TElectronicFence;
+import com.ruoyi.system.domain.TElectronicFenceKey;
+import com.ruoyi.system.domain.TElectronicFenceService;
+import com.ruoyi.system.domain.TShouhuanInfo;
+import com.ruoyi.system.mapper.TDeviceListMapper;
+import com.ruoyi.system.mapper.TElectronicFenceMapper;
+import com.ruoyi.system.service.ITElectronicFenceKeyService;
+import com.ruoyi.system.service.ITElectronicFenceServiceService;
+import com.ruoyi.system.service.impl.TElectronicFenceServiceImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ClassName: GeofenceDeleteTiming
+ * @Author: 于学智
+ * @Description: 高德地图删除围栏定时任务
+ * @CreateDate: 2023/9/14 18:22
+ * @Version: 1.0
+ * @E-mail:18722650553@139.com
+ * @Link:https://github.com/18722650553
+ */
+
+@Component("geofenceDeleteTiming")
+public class GeofenceDeleteTiming {
+    private static final Logger log = LoggerFactory.getLogger(GeofenceDeleteTiming.class);
+
+    @Autowired
+    private TElectronicFenceMapper tElectronicFenceMapper;
+    @Autowired
+    private ITElectronicFenceKeyService iElectronicFenceKeyService;
+    @Autowired
+    private ITElectronicFenceServiceService iElectronicFenceServiceService;
+
+    /**
+     * 检测已删除的围栏信息
+     */
+    public void checkGeofenceDelete() {
+        //获取表中已删除的围栏
+        List<TElectronicFence> tElectronicFences = tElectronicFenceMapper.selectTElectronicFenceByDelState(1);
+        if (tElectronicFences != null && !tElectronicFences.isEmpty()) {
+            //获取单个要删除的围栏信息
+            for (TElectronicFence fence : tElectronicFences) {
+                //通过围栏serviceId获取service
+                TElectronicFenceService fenceService = iElectronicFenceServiceService.selectTElectronicFenceServiceById(fence.getServiceId());
+                if (fenceService == null) {
+                    log.error("围栏对应的高德服务为空,围栏ID:{}.", fence.getServiceId());
+                    continue;
+                }
+                TElectronicFenceKey tElectronicFenceKey = iElectronicFenceKeyService.selectTElectronicFenceKeyById(fenceService.getKeyId());
+                if (tElectronicFenceKey == null) {
+                    log.error("围栏对应的高德key为空,围栏ID:{}. 服务ID:{}", fence.getId(), fence.getServiceId());
+                    continue;
+                }
+                //TODO 单个删除围栏,后期整合
+                String result = sendGeoDel(tElectronicFenceKey.getAmapKey(), fenceService.getAmapSid(), fence.getGfid());
+                if (!StringUtils.isEmpty(result)) {
+                    List<Long> gfids = JSONObject.parseArray(result, Long.class);
+                    gfids.add(1140869L);
+                    if (gfids!=null&&!gfids.isEmpty()){
+                        //数据库真是删除
+                        tElectronicFenceMapper.deleteTElectronicFenceByGfids(gfids.toArray(new Long[0]));
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * 通过高德接口删除围栏
+     *
+     * @param fenceKey
+     * @param fenceService
+     * @param gfids
+     * @return
+     */
+    private String sendGeoDel(String fenceKey, String fenceService, String gfids) {
+        //创建圆形围栏
+        Map<Object, Object> params = new HashMap();
+        params.put("key", fenceKey);
+        params.put("sid", fenceService);
+        params.put("gfids", gfids);
+        String paramsString = HttpUtils.getParamsToString(params);
+        // 去掉最后一个"&"符号
+        String result = HttpUtils.sendPost(AMapConstants.AMAP_TRACK_SERVICE_DELETE, paramsString);
+        log.info("删除高德围栏Url:{} ,\n返回结果:{}", AMapConstants.AMAP_TRACK_SERVICE_DELETE + "?" + paramsString, result);
+        AMapResult<Map<String, String>> aMapResult = JSONObject.parseObject(result, AMapResult.class);
+        if (aMapResult != null && aMapResult.getData() != null && aMapResult.getData().containsKey("gfids")) {
+            return String.valueOf(aMapResult.getData().get("gfids"));
+        }
+        log.info("删除高德围栏异常,key:{},gfids:{} ,code:{} ,msg:{}", fenceKey, gfids, aMapResult.getErrmsg(), aMapResult.getErrdetail());
+        return null;
+    }
+}

+ 82 - 0
ruoyi-system/src/main/resources/mapper/system/TElectronicFenceKeyMapper.xml

@@ -0,0 +1,82 @@
+<?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="com.ruoyi.system.mapper.TElectronicFenceKeyMapper">
+
+    <resultMap type="TElectronicFenceKey" id="TElectronicFenceKeyResult">
+        <result property="id" column="id"/>
+        <result property="amapKey" column="amap_key"/>
+        <result property="createTime" column="create_time"/>
+        <result property="updateTime" column="update_time"/>
+        <result property="amapName" column="amap_name"/>
+        <result property="amapDesc" column="amap_desc"/>
+    </resultMap>
+
+    <sql id="selectTElectronicFenceKeyVo">
+        select id, amap_key, create_time, update_time, amap_name, amap_desc
+        from t_electronic_fence_key
+    </sql>
+
+    <select id="selectTElectronicFenceKeyList" parameterType="TElectronicFenceKey"
+            resultMap="TElectronicFenceKeyResult">
+        <include refid="selectTElectronicFenceKeyVo"/>
+        <where>
+            <if test="amapKey != null  and amapKey != ''">and amap_key = #{amapKey}</if>
+            <if test="amapName != null  and amapName != ''">and amap_name like concat('%', #{amapName}, '%')</if>
+            <if test="amapDesc != null  and amapDesc != ''">and amap_desc = #{amapDesc}</if>
+        </where>
+    </select>
+
+    <select id="selectTElectronicFenceKeyById" parameterType="Long" resultMap="TElectronicFenceKeyResult">
+        <include refid="selectTElectronicFenceKeyVo"/>
+        where id = #{id}
+    </select>
+
+    <select id="selectTElectronicFenceKey" resultMap="TElectronicFenceKeyResult">
+        <include refid="selectTElectronicFenceKeyVo"/>
+    </select>
+
+    <insert id="insertTElectronicFenceKey" parameterType="TElectronicFenceKey" useGeneratedKeys="true" keyProperty="id">
+        insert into t_electronic_fence_key
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="amapKey != null and amapKey != ''">amap_key,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateTime != null">update_time,</if>
+            <if test="amapName != null">amap_name,</if>
+            <if test="amapDesc != null">amap_desc,</if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="amapKey != null and amapKey != ''">#{amapKey},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+            <if test="amapName != null">#{amapName},</if>
+            <if test="amapDesc != null">#{amapDesc},</if>
+        </trim>
+    </insert>
+
+    <update id="updateTElectronicFenceKey" parameterType="TElectronicFenceKey">
+        update t_electronic_fence_key
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="amapKey != null and amapKey != ''">amap_key = #{amapKey},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="amapName != null">amap_name = #{amapName},</if>
+            <if test="amapDesc != null">amap_desc = #{amapDesc},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteTElectronicFenceKeyById" parameterType="Long">
+        delete
+        from t_electronic_fence_key
+        where id = #{id}
+    </delete>
+
+    <delete id="deleteTElectronicFenceKeyByIds" parameterType="String">
+        delete from t_electronic_fence_key where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 155 - 0
ruoyi-system/src/main/resources/mapper/system/TElectronicFenceMapper.xml

@@ -0,0 +1,155 @@
+<?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="com.ruoyi.system.mapper.TElectronicFenceMapper">
+
+    <resultMap type="TElectronicFence" id="TElectronicFenceResult">
+        <result property="id" column="id"/>
+        <result property="name" column="name"/>
+        <result property="startTime" column="start_time"/>
+        <result property="endTime" column="end_time"/>
+        <result property="updateTime" column="update_time"/>
+        <result property="createTime" column="create_time"/>
+        <result property="eState" column="e_state"/>
+        <result property="eType" column="e_type"/>
+        <result property="eDesc" column="e_desc"/>
+        <result property="gfid" column="gfid"/>
+        <result property="delState" column="del_state"/>
+        <result property="userId" column="user_id"/>
+        <result property="deviceId" column="device_id"/>
+        <result property="serviceId" column="service_id"/>
+    </resultMap>
+
+    <sql id="selectTElectronicFenceVo">
+        select id,
+               name,
+               start_time,
+               end_time,
+               update_time,
+               create_time,
+               e_state,
+               e_type,
+               e_desc,
+               gfid,
+               del_state,
+               user_id,
+               device_id,
+               service_id
+        from t_electronic_fence
+    </sql>
+
+    <select id="selectTElectronicFenceList" parameterType="TElectronicFence" resultMap="TElectronicFenceResult">
+        <include refid="selectTElectronicFenceVo"/>
+        <where>
+            <if test="name != null  and name != ''">and name like concat('%', #{name}, '%')</if>
+            <if test="startTime != null ">and start_time = #{startTime}</if>
+            <if test="endTime != null ">and end_time = #{endTime}</if>
+            <if test="eState != null ">and e_state = #{eState}</if>
+            <if test="eType != null ">and e_type = #{eType}</if>
+            <if test="eDesc != null  and eDesc != ''">and e_desc = #{eDesc}</if>
+            <if test="gfid != null ">and gfid = #{gfid}</if>
+            <if test="delState != null ">and del_state = #{delState}</if>
+            <if test="userId != null ">and user_id = #{userId}</if>
+            <if test="deviceId != null ">and device_id = #{deviceId}</if>
+            <if test="serviceId != null ">and service_id = #{serviceId}</if>
+        </where>
+    </select>
+
+    <select id="selectTElectronicFenceById" parameterType="Long" resultMap="TElectronicFenceResult">
+        <include refid="selectTElectronicFenceVo"/>
+        where id = #{id}
+    </select>
+
+    <select id="selectTElectronicFenceListByDeviceId" parameterType="Long" resultMap="TElectronicFenceResult">
+        <include refid="selectTElectronicFenceVo"/>
+        WHERE device_id = #{deviceId} AND del_state = 0
+    </select>
+
+    <select id="selectTElectronicFenceByDelState" parameterType="integer"
+            resultMap="TElectronicFenceResult">
+        <include refid="selectTElectronicFenceVo"/>
+        WHERE del_state= #{delState}
+    </select>
+
+    <insert id="insertTElectronicFence" parameterType="TElectronicFence" useGeneratedKeys="true" keyProperty="id">
+        insert into t_electronic_fence
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="name != null and name != ''">name,</if>
+            <if test="startTime != null">start_time,</if>
+            <if test="endTime != null">end_time,</if>
+            <if test="updateTime != null">update_time,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="eState != null">e_state,</if>
+            <if test="eType != null">e_type,</if>
+            <if test="eDesc != null">e_desc,</if>
+            <if test="gfid != null">gfid,</if>
+            <if test="delState != null">del_state,</if>
+            <if test="userId != null">user_id,</if>
+            <if test="deviceId != null">device_id,</if>
+            <if test="serviceId != null">service_id,</if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="name != null and name != ''">#{name},</if>
+            <if test="startTime != null">#{startTime},</if>
+            <if test="endTime != null">#{endTime},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="eState != null">#{eState},</if>
+            <if test="eType != null">#{eType},</if>
+            <if test="eDesc != null">#{eDesc},</if>
+            <if test="gfid != null">#{gfid},</if>
+            <if test="delState != null">#{delState},</if>
+            <if test="userId != null">#{userId},</if>
+            <if test="deviceId != null">#{deviceId},</if>
+            <if test="serviceId != null">#{serviceId},</if>
+        </trim>
+    </insert>
+
+    <update id="updateTElectronicFence" parameterType="TElectronicFence">
+        update t_electronic_fence
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="name != null and name != ''">name = #{name},</if>
+            <if test="startTime != null">start_time = #{startTime},</if>
+            <if test="endTime != null">end_time = #{endTime},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="eState != null">e_state = #{eState},</if>
+            <if test="eType != null">e_type = #{eType},</if>
+            <if test="eDesc != null">desc = #{eDesc},</if>
+            <if test="gfid != null">gfid = #{gfid},</if>
+            <if test="delState != null">del_state = #{delState},</if>
+            <if test="userId != null">user_id = #{userId},</if>
+            <if test="deviceId != null">device_id = #{deviceId},</if>
+            <if test="serviceId != null">service_id = #{serviceId},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteTElectronicFenceById" parameterType="Long">
+        delete
+        from t_electronic_fence
+        where id = #{id}
+    </delete>
+
+    <delete id="deleteTElectronicFenceByIds" parameterType="String">
+        delete from t_electronic_fence where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+
+    <delete id="deleteTElectronicFenceStateByIds" parameterType="String">
+        UPDATE t_electronic_fence SET del_state = 1 WHERE id IN
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+
+    <delete id="deleteTElectronicFenceByGfids">
+        delete from t_electronic_fence where gfid in
+        <foreach item="gfid" collection="array" open="(" separator="," close=")">
+            #{gfid}
+        </foreach>
+    </delete>
+</mapper>

+ 89 - 0
ruoyi-system/src/main/resources/mapper/system/TElectronicFenceServiceMapper.xml

@@ -0,0 +1,89 @@
+<?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="com.ruoyi.system.mapper.TElectronicFenceServiceMapper">
+
+    <resultMap type="TElectronicFenceService" id="TElectronicFenceServiceResult">
+        <result property="id" column="id"/>
+        <result property="keyId" column="key_id"/>
+        <result property="amapSid" column="amap_sid"/>
+        <result property="createTime" column="create_time"/>
+        <result property="updateTime" column="update_time"/>
+        <result property="amapName" column="amap_name"/>
+        <result property="amapDesc" column="amap_desc"/>
+    </resultMap>
+
+    <sql id="selectTElectronicFenceServiceVo">
+        select id, key_id, amap_sid, create_time, update_time, amap_name, amap_desc
+        from t_electronic_fence_service
+    </sql>
+
+    <select id="selectTElectronicFenceServiceList" parameterType="TElectronicFenceService"
+            resultMap="TElectronicFenceServiceResult">
+        <include refid="selectTElectronicFenceServiceVo"/>
+        <where>
+            <if test="keyId != null ">and key_id = #{keyId}</if>
+            <if test="amapSid != null  and amapSid != ''">and amap_sid = #{amapSid}</if>
+            <if test="amapName != null  and amapName != ''">and amap_name like concat('%', #{amapName}, '%')</if>
+            <if test="amapDesc != null  and amapDesc != ''">and amap_desc = #{amapDesc}</if>
+        </where>
+    </select>
+
+    <select id="selectTElectronicFenceServiceById" parameterType="Long" resultMap="TElectronicFenceServiceResult">
+        <include refid="selectTElectronicFenceServiceVo"/>
+        where id = #{id}
+    </select>
+
+    <select id="selectTElectronicFenceServiceByKeyId" resultMap="TElectronicFenceServiceResult">
+        <include refid="selectTElectronicFenceServiceVo"/>
+        where key_id = #{key_id}
+    </select>
+
+    <insert id="insertTElectronicFenceService" parameterType="TElectronicFenceService" useGeneratedKeys="true"
+            keyProperty="id">
+        insert into t_electronic_fence_service
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="keyId != null">key_id,</if>
+            <if test="amapSid != null and amapSid != ''">amap_sid,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateTime != null">update_time,</if>
+            <if test="amapName != null">amap_name,</if>
+            <if test="amapDesc != null">amap_desc,</if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="keyId != null">#{keyId},</if>
+            <if test="amapSid != null and amapSid != ''">#{amapSid},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+            <if test="amapName != null">#{amapName},</if>
+            <if test="amapDesc != null">#{amapDesc},</if>
+        </trim>
+    </insert>
+
+    <update id="updateTElectronicFenceService" parameterType="TElectronicFenceService">
+        update t_electronic_fence_service
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="keyId != null">key_id = #{keyId},</if>
+            <if test="amapSid != null and amapSid != ''">amap_sid = #{amapSid},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="amapName != null">amap_name = #{amapName},</if>
+            <if test="amapDesc != null">amap_desc = #{amapDesc},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteTElectronicFenceServiceById" parameterType="Long">
+        delete
+        from t_electronic_fence_service
+        where id = #{id}
+    </delete>
+
+    <delete id="deleteTElectronicFenceServiceByIds" parameterType="String">
+        delete from t_electronic_fence_service where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>