Browse Source

完善电子地图相关接口

hanzhengyi 5 days ago
parent
commit
9842472de6
15 changed files with 533 additions and 7 deletions
  1. 50 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/controller/web/SasMapController.java
  2. 46 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/domain/SasPicSource.java
  3. 10 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/mapper/SasPicSourceMapper.java
  4. 35 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/service/SasMapService.java
  5. 10 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/service/SasPicSourceService.java
  6. 12 4
      service-sas/service-sas-biz/src/main/java/com/usky/sas/service/impl/SasDeviceServiceImpl.java
  7. 159 1
      service-sas/service-sas-biz/src/main/java/com/usky/sas/service/impl/SasMapServiceImpl.java
  8. 14 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/service/impl/SasPicSourceServiceImpl.java
  9. 61 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/service/vo/DeviceImportExcelVO.java
  10. 24 2
      service-sas/service-sas-biz/src/main/java/com/usky/sas/service/vo/MapListItem.java
  11. 4 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/service/vo/MapPageRequest.java
  12. 31 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/service/vo/PicAddRequest.java
  13. 25 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/service/vo/PicSourceInfo.java
  14. 21 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/service/vo/PicSourcePageRequest.java
  15. 31 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/service/vo/PicSourceUpdateRequest.java

+ 50 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/controller/web/SasMapController.java

@@ -9,6 +9,10 @@ import com.usky.sas.service.vo.MapPageRequest;
 import com.usky.sas.service.vo.MapSaveRequest;
 import com.usky.sas.service.vo.MapSaveWithDevicesRequest;
 import com.usky.sas.service.vo.MapTreeItem;
+import com.usky.sas.service.vo.PicAddRequest;
+import com.usky.sas.service.vo.PicSourceInfo;
+import com.usky.sas.service.vo.PicSourcePageRequest;
+import com.usky.sas.service.vo.PicSourceUpdateRequest;
 import lombok.Data;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.DeleteMapping;
@@ -32,6 +36,10 @@ import org.springframework.web.bind.annotation.RestController;
      * DELETE /prod-api/service-sas/map/{mapId}/device/{deviceId}
      * GET /prod-api/service-sas/map/tree
      * POST /prod-api/service-sas/map/saveMapInfo
+     * POST /prod-api/service-sas/map/pic  新增图片记录(不入库文件,仅 url/path)
+     * GET  /prod-api/service-sas/map/pic/source  分页查询图片资源(可按 picType 筛选)
+     * PUT  /prod-api/service-sas/map/pic/source/{id}  修改图片资源
+     * DELETE /prod-api/service-sas/map/pic/source/{id}  删除图片资源
  */
 @RestController
 @RequestMapping("/map")
@@ -98,6 +106,43 @@ public class SasMapController {
         return ApiResult.success(sasMapService.getMapTree());
     }
 
+    /**
+     * 新增图片记录(不处理二进制文件上传,仅根据 url/path 写入 sas_pic)
+     */
+    @PostMapping("/pic")
+    public ApiResult<AddPicResponse> addPic(@RequestBody PicAddRequest request) {
+        String id = sasMapService.addPic(request);
+        AddPicResponse resp = new AddPicResponse();
+        resp.setId(id);
+        return ApiResult.success(resp);
+    }
+
+    /**
+     * 分页查询图片资源(sas_pic_source),可按 picType 筛选,每条带图片完整 URL
+     */
+    @GetMapping("/pic/source")
+    public ApiResult<CommonPage<PicSourceInfo>> getPicSource(PicSourcePageRequest request) {
+        return ApiResult.success(sasMapService.getPicSource(request));
+    }
+
+    /**
+     * 修改图片资源(更新 sas_pic_source 及可选的关联 sas_pic.url/path)
+     */
+    @PutMapping("/pic/source/{id}")
+    public ApiResult<Void> updatePicSource(@PathVariable("id") String id, @RequestBody PicSourceUpdateRequest request) {
+        sasMapService.updatePicSource(id, request);
+        return ApiResult.success();
+    }
+
+    /**
+     * 删除图片资源(仅删除 sas_pic_source 记录)
+     */
+    @DeleteMapping("/pic/source/{id}")
+    public ApiResult<Void> deletePicSource(@PathVariable("id") String id) {
+        sasMapService.deletePicSource(id);
+        return ApiResult.success();
+    }
+
     @Data
     public static class CreateMapResponse {
         private String id;
@@ -107,5 +152,10 @@ public class SasMapController {
     public static class CreateMapDeviceResponse {
         private String id;
     }
+
+    @Data
+    public static class AddPicResponse {
+        private String id;
+    }
 }
 

+ 46 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/domain/SasPicSource.java

@@ -0,0 +1,46 @@
+package com.usky.sas.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 图片资源表(sas_pic_source)
+ */
+@Data
+@TableName("sas_pic_source")
+public class SasPicSource {
+
+    @TableId(value = "id", type = IdType.INPUT)
+    private String id;
+
+    /** 图片名称 */
+    private String name;
+
+    /** 描述信息 */
+    private String remark;
+
+    /** 图片类型(对应 sas_pic_type) */
+    @TableField("pic_type")
+    private Integer picType;
+
+    /** 子类型 */
+    private Integer subtype;
+
+    /** 标签 */
+    private String tag;
+
+    /** 图片地址 id(关联 sas_pic.id) */
+    @TableField("pic_id")
+    private String picId;
+
+    @TableField("create_time")
+    private LocalDateTime createTime;
+
+    @TableField("update_time")
+    private LocalDateTime updateTime;
+}

+ 10 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/mapper/SasPicSourceMapper.java

@@ -0,0 +1,10 @@
+package com.usky.sas.mapper;
+
+import com.usky.common.mybatis.core.CrudMapper;
+import com.usky.sas.domain.SasPicSource;
+
+/**
+ * 图片资源表 Mapper 接口
+ */
+public interface SasPicSourceMapper extends CrudMapper<SasPicSource> {
+}

+ 35 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/service/SasMapService.java

@@ -10,6 +10,10 @@ import com.usky.sas.service.vo.MapSaveRequest;
 import com.usky.sas.service.vo.MapSaveWithDevicesRequest;
 import com.usky.sas.service.vo.MapTreeItem;
 import com.usky.sas.service.vo.MapInfoVo;
+import com.usky.sas.service.vo.PicAddRequest;
+import com.usky.sas.service.vo.PicSourceInfo;
+import com.usky.sas.service.vo.PicSourcePageRequest;
+import com.usky.sas.service.vo.PicSourceUpdateRequest;
 
 public interface SasMapService extends CrudService<SasMaps> {
 
@@ -47,5 +51,36 @@ public interface SasMapService extends CrudService<SasMaps> {
      * @return 地图详情,不存在则 null
      */
     MapInfoVo getMapInfo(String mapId);
+
+    /**
+     * 新增图片记录(不入库二进制文件,仅根据 url/path 写入 sas_pic)
+     *
+     * @param request 图片地址信息
+     * @return 新建图片主键 id(sas_pic.id)
+     */
+    String addPic(PicAddRequest request);
+
+    /**
+     * 分页查询图片资源(sas_pic_source),可按 picType 筛选,每条记录带图片完整访问 URL
+     *
+     * @param request 分页及 picType 筛选参数
+     * @return 分页结果
+     */
+    CommonPage<PicSourceInfo> getPicSource(PicSourcePageRequest request);
+
+    /**
+     * 修改图片资源(更新 sas_pic_source 及可选的关联 sas_pic.url/path)
+     *
+     * @param id      图片资源主键(sas_pic_source.id)
+     * @param request 要更新的字段
+     */
+    void updatePicSource(String id, PicSourceUpdateRequest request);
+
+    /**
+     * 删除图片资源(仅删除 sas_pic_source 记录,不删除关联的 sas_pic)
+     *
+     * @param id 图片资源主键(sas_pic_source.id)
+     */
+    void deletePicSource(String id);
 }
 

+ 10 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/service/SasPicSourceService.java

@@ -0,0 +1,10 @@
+package com.usky.sas.service;
+
+import com.usky.common.mybatis.core.CrudService;
+import com.usky.sas.domain.SasPicSource;
+
+/**
+ * 图片资源服务接口
+ */
+public interface SasPicSourceService extends CrudService<SasPicSource> {
+}

+ 12 - 4
service-sas/service-sas-biz/src/main/java/com/usky/sas/service/impl/SasDeviceServiceImpl.java

@@ -600,18 +600,26 @@ public class SasDeviceServiceImpl extends AbstractCrudService<SasDeviceMapper, S
         params.setTitleRows(1);
         String err = "文件导入失败";
         try {
-            List<DeviceImportTemplateVO> rows = ExcelImportUtil.importExcel(
-                    file.getInputStream(), DeviceImportTemplateVO.class, params);
+            List<DeviceImportExcelVO> rows = ExcelImportUtil.importExcel(
+                    file.getInputStream(), DeviceImportExcelVO.class, params);
             if (rows == null || rows.isEmpty()) {
                 throw new BusinessException("文件不能为空");
             }
             int index = 0;
-            for (DeviceImportTemplateVO row : rows) {
+            for (DeviceImportExcelVO row : rows) {
                 index++;
+                // 跳过空行:设备编号、IP、端口、设备类型都为空时视为空行
+                if ((row.getDeviceId() == null || row.getDeviceId().trim().isEmpty())
+                        && (row.getIpAddr() == null || row.getIpAddr().trim().isEmpty())
+                        && row.getPort() == null
+                        && row.getDeviceType() == null) {
+                    continue;
+                }
                 if (row.getDeviceType() == null
                         || row.getDeviceId() == null || row.getDeviceId().isEmpty()
+                        || row.getIpAddr() == null || row.getIpAddr().isEmpty()
                         || row.getPort() == null) {
-                    throw new BusinessException("第" + (index + 1) + "行数据导入失败,设备类型、设备编号、端口为必填");
+                    throw new BusinessException("第" + (index + 1) + "行数据不完整,设备类型、设备编号、设备IP、端口为必填");
                 }
                 int channel = row.getChannel() != null ? row.getChannel() : 0;
                 LambdaQueryWrapper<SasDevice> wrapper = new LambdaQueryWrapper<>();

+ 159 - 1
service-sas/service-sas-biz/src/main/java/com/usky/sas/service/impl/SasMapServiceImpl.java

@@ -9,6 +9,7 @@ import com.usky.sas.domain.SasMapDevice;
 import com.usky.sas.domain.SasMaps;
 import com.usky.sas.domain.SasDevice;
 import com.usky.sas.domain.SasPic;
+import com.usky.sas.domain.SasPicSource;
 import com.usky.sas.enums.SystemTypeCodeEnum;
 import com.usky.sas.mapper.SasMapDeviceMapper;
 import com.usky.sas.mapper.SasMapsMapper;
@@ -16,6 +17,8 @@ import com.usky.sas.mapper.SasPicMapper;
 import com.usky.sas.mapper.SasDeviceMapper;
 import com.usky.sas.common.util.GetIpUtils;
 import com.usky.sas.service.SasMapService;
+import com.usky.sas.service.SasPicService;
+import com.usky.sas.service.SasPicSourceService;
 import com.usky.sas.service.vo.MapDeviceBindRequest;
 import com.usky.sas.service.vo.MapListItem;
 import com.usky.sas.service.vo.MapPageRequest;
@@ -23,11 +26,17 @@ import com.usky.sas.service.vo.MapSaveRequest;
 import com.usky.sas.service.vo.MapSaveWithDevicesRequest;
 import com.usky.sas.service.vo.MapTreeItem;
 import com.usky.sas.service.vo.MapInfoVo;
+import com.usky.sas.service.vo.PicAddRequest;
+import com.usky.sas.service.vo.PicSourceInfo;
+import com.usky.sas.service.vo.PicSourcePageRequest;
+import com.usky.sas.service.vo.PicSourceUpdateRequest;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
+import com.usky.common.core.exception.BusinessException;
+
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.util.Collections;
@@ -52,6 +61,12 @@ public class SasMapServiceImpl extends AbstractCrudService<SasMapsMapper, SasMap
     @Autowired
     private SasDeviceMapper sasDeviceMapper;
 
+    @Autowired
+    private SasPicService sasPicService;
+
+    @Autowired
+    private SasPicSourceService sasPicSourceService;
+
     @Value("${server.protocol:http}")
     private String protocol;
 
@@ -62,9 +77,12 @@ public class SasMapServiceImpl extends AbstractCrudService<SasMapsMapper, SasMap
     public CommonPage<MapListItem> page(MapPageRequest request) {
         IPage<SasMaps> page = new Page<>(request.getCurrent(), request.getSize());
         LambdaQueryWrapper<SasMaps> wrapper = new LambdaQueryWrapper<>();
-        if (request.getParentId() != null) {
+        if (request.getParentId() != null && !request.getParentId().isEmpty()) {
             wrapper.eq(SasMaps::getParentId, request.getParentId());
         }
+        if (request.getMapId() != null && !request.getMapId().isEmpty()) {
+            wrapper.eq(SasMaps::getId, request.getMapId());
+        }
         wrapper.orderByDesc(SasMaps::getCreateTime);
         page = this.page(page, wrapper);
 
@@ -96,16 +114,48 @@ public class SasMapServiceImpl extends AbstractCrudService<SasMapsMapper, SasMap
             item.setBackImgId(map.getBackImgId());
             item.setCreateTime(map.getCreateTime());
             item.setUpdateTime(map.getUpdateTime());
+            if (map.getBackImgId() != null && !map.getBackImgId().isEmpty()) {
+                SasPic backPic = sasPicMapper.selectById(map.getBackImgId());
+                if (backPic != null) {
+                    String baseUrl = protocol + "://" + GetIpUtils.getServerIP() + ":" + port;
+                    String path = (backPic.getUrl() != null ? backPic.getUrl() : "") + (backPic.getPath() != null ? backPic.getPath() : "");
+                    item.setBackImgUrl(baseUrl + path);
+                }
+            }
 
             List<SasMapDevice> devices = deviceGroup.getOrDefault(map.getId(), Collections.emptyList());
             List<MapListItem.MapDeviceItem> deviceItems = devices.stream().map(d -> {
                 MapListItem.MapDeviceItem di = new MapListItem.MapDeviceItem();
                 di.setId(d.getId());
                 di.setDeviceId(d.getDeviceId());
+                di.setMapId(d.getMapId());
+                di.setImgId(d.getImgId());
                 di.setDeviceName(d.getText());
                 di.setType(d.getType());
                 di.setX(d.getX() != null ? d.getX().doubleValue() : null);
                 di.setY(d.getY() != null ? d.getY().doubleValue() : null);
+                if (d.getImgId() != null && !d.getImgId().isEmpty()) {
+                    SasPic imgPic = sasPicMapper.selectById(d.getImgId());
+                    if (imgPic != null) {
+                        String baseUrl = protocol + "://" + GetIpUtils.getServerIP() + ":" + port;
+                        String path = (imgPic.getUrl() != null ? imgPic.getUrl() : "") + (imgPic.getPath() != null ? imgPic.getPath() : "");
+                        di.setImgUrl(baseUrl + path);
+                    }
+                }
+                SasDevice device = sasDeviceMapper.selectById(d.getDeviceId());
+                if (device != null) {
+                    MapListItem.DeviceInfoVo deviceInfo = new MapListItem.DeviceInfoVo();
+                    deviceInfo.setId(device.getId());
+                    deviceInfo.setDeviceId(device.getDeviceId());
+                    deviceInfo.setChannel(device.getChannel());
+                    deviceInfo.setIpAddr(device.getIpAddr());
+                    deviceInfo.setPort(device.getPort());
+                    deviceInfo.setAddress(device.getAddress());
+                    deviceInfo.setNote(device.getNote());
+                    SystemTypeCodeEnum typeEnum = SystemTypeCodeEnum.getByCode(device.getDeviceType());
+                    deviceInfo.setDeviceType(typeEnum != null ? typeEnum.getMessage() : null);
+                    di.setDeviceInfo(deviceInfo);
+                }
                 return di;
             }).collect(Collectors.toList());
             item.setDevices(deviceItems);
@@ -435,6 +485,114 @@ public class SasMapServiceImpl extends AbstractCrudService<SasMapsMapper, SasMap
         return vo;
     }
 
+    @Override
+    public String addPic(PicAddRequest request) {
+        if (request == null || request.getUrl() == null || request.getUrl().isEmpty()) {
+            throw new BusinessException("图片地址 url 为必填");
+        }
+        SasPic pic = new SasPic();
+        pic.setId(UUID.randomUUID().toString());
+        pic.setUrl(request.getUrl());
+        pic.setPath(request.getPath());
+        LocalDateTime now = LocalDateTime.now();
+        pic.setCreateTime(now);
+        pic.setUpdateTime(now);
+        sasPicService.save(pic);
+
+        SasPicSource picSource = new SasPicSource();
+        picSource.setId(UUID.randomUUID().toString());
+        picSource.setPicId(pic.getId());
+        picSource.setName(request.getName());
+        picSource.setRemark(request.getRemark());
+        picSource.setPicType(request.getPicType());
+        picSource.setSubtype(request.getSubtype());
+        picSource.setTag(request.getTag());
+        picSource.setCreateTime(now);
+        picSource.setUpdateTime(now);
+        sasPicSourceService.save(picSource);
+
+        return pic.getId();
+    }
+
+    @Override
+    public CommonPage<PicSourceInfo> getPicSource(PicSourcePageRequest request) {
+        if (request == null) {
+            request = new PicSourcePageRequest();
+        }
+        Page<SasPicSource> page = new Page<>(
+                request.getCurrent() != null ? request.getCurrent() : 1L,
+                request.getSize() != null ? request.getSize() : 10L);
+        LambdaQueryWrapper<SasPicSource> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(request.getPicType() != null, SasPicSource::getPicType, request.getPicType());
+        com.baomidou.mybatisplus.core.metadata.IPage<SasPicSource> sourcePage = sasPicSourceService.page(page, wrapper);
+        List<PicSourceInfo> list = sourcePage.getRecords().stream().map(picSource -> {
+            PicSourceInfo info = new PicSourceInfo();
+            BeanUtils.copyProperties(picSource, info);
+            if (picSource.getPicId() != null && !picSource.getPicId().isEmpty()) {
+                SasPic pic = sasPicService.getById(picSource.getPicId());
+                if (pic != null) {
+                    String path = (pic.getUrl() != null ? pic.getUrl() : "") + (pic.getPath() != null ? pic.getPath() : "");
+                    info.setPicUrl(path);
+                }
+            }
+            return info;
+        }).collect(Collectors.toList());
+        return new CommonPage<>(list, sourcePage.getTotal(), sourcePage.getCurrent(), sourcePage.getSize());
+    }
+
+    @Override
+    public void updatePicSource(String id, PicSourceUpdateRequest request) {
+        if (id == null || id.isEmpty()) {
+            throw new BusinessException("图片资源 id 不能为空");
+        }
+        SasPicSource picSource = sasPicSourceService.getById(id);
+        if (picSource == null) {
+            throw new BusinessException("图片资源不存在");
+        }
+        if (request != null) {
+            if (request.getName() != null) {
+                picSource.setName(request.getName());
+            }
+            if (request.getRemark() != null) {
+                picSource.setRemark(request.getRemark());
+            }
+            if (request.getPicType() != null) {
+                picSource.setPicType(request.getPicType());
+            }
+            if (request.getSubtype() != null) {
+                picSource.setSubtype(request.getSubtype());
+            }
+            if (request.getTag() != null) {
+                picSource.setTag(request.getTag());
+            }
+            LocalDateTime now = LocalDateTime.now();
+            picSource.setUpdateTime(now);
+            sasPicSourceService.updateById(picSource);
+
+            if ((request.getUrl() != null || request.getPath() != null) && picSource.getPicId() != null && !picSource.getPicId().isEmpty()) {
+                SasPic pic = sasPicService.getById(picSource.getPicId());
+                if (pic != null) {
+                    if (request.getUrl() != null) {
+                        pic.setUrl(request.getUrl());
+                    }
+                    if (request.getPath() != null) {
+                        pic.setPath(request.getPath());
+                    }
+                    pic.setUpdateTime(now);
+                    sasPicService.updateById(pic);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void deletePicSource(String id) {
+        if (id == null || id.isEmpty()) {
+            throw new BusinessException("图片资源 id 不能为空");
+        }
+        sasPicSourceService.removeById(id);
+    }
+
     /**
      * 递归删除地图及其子地图,同时删除绑定设备
      */

+ 14 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/service/impl/SasPicSourceServiceImpl.java

@@ -0,0 +1,14 @@
+package com.usky.sas.service.impl;
+
+import com.usky.common.mybatis.core.AbstractCrudService;
+import com.usky.sas.domain.SasPicSource;
+import com.usky.sas.mapper.SasPicSourceMapper;
+import com.usky.sas.service.SasPicSourceService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 图片资源服务实现
+ */
+@Service
+public class SasPicSourceServiceImpl extends AbstractCrudService<SasPicSourceMapper, SasPicSource> implements SasPicSourceService {
+}

+ 61 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/service/vo/DeviceImportExcelVO.java

@@ -0,0 +1,61 @@
+package com.usky.sas.service.vo;
+
+import cn.afterturn.easypoi.excel.annotation.Excel;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 设备 Excel 导入行(EasyPoi 解析用,列名需与导出的模板一致)
+ */
+@Data
+public class DeviceImportExcelVO {
+
+    @Excel(name = "设备类型(必填)")
+    private Integer deviceType;
+
+    @Excel(name = "设备编号(必填)")
+    private String deviceId;
+
+    @Excel(name = "设备IP(可选)")
+    private String ipAddr;
+
+    @Excel(name = "端口(必填)")
+    private Integer port;
+
+    @Excel(name = "通道号")
+    private Integer channel;
+
+    @Excel(name = "视频设备类型")
+    private Integer videoDeviceType;
+
+    @Excel(name = "视频协议")
+    private Integer videoProtocol;
+
+    @Excel(name = "用户名")
+    private String username;
+
+    @Excel(name = "密码")
+    private String password;
+
+    @Excel(name = "备注")
+    private String note;
+
+    @Excel(name = "安装位置")
+    private String address;
+
+    @Excel(name = "部位编码(houseCode)")
+    private String houseCode;
+
+    @Excel(name = "经度")
+    private BigDecimal lon;
+
+    @Excel(name = "纬度")
+    private BigDecimal lat;
+
+    @Excel(name = "高度")
+    private BigDecimal alt;
+
+    @Excel(name = "楼层")
+    private Integer floor;
+}

+ 24 - 2
service-sas/service-sas-biz/src/main/java/com/usky/sas/service/vo/MapListItem.java

@@ -6,7 +6,7 @@ import java.time.LocalDateTime;
 import java.util.List;
 
 /**
- * 电子地图配置列表项,包含地图基础信息及绑定设备简要信息
+ * 电子地图配置列表项,包含地图基础信息、背景图完整 URL、绑定设备及设备点位图标 URL、设备详情
  */
 @Data
 public class MapListItem {
@@ -29,12 +29,15 @@ public class MapListItem {
 
     private String backImgId;
 
+    /** 背景图完整访问 URL(protocol + host + port + pic.url/path) */
+    private String backImgUrl;
+
     private LocalDateTime createTime;
 
     private LocalDateTime updateTime;
 
     /**
-     * 绑定在该地图上的设备列表
+     * 绑定在该地图上的设备列表(含点位图标 URL、设备详情及设备类型名称)
      */
     private List<MapDeviceItem> devices;
 
@@ -42,10 +45,29 @@ public class MapListItem {
     public static class MapDeviceItem {
         private String id;
         private String deviceId;
+        private String mapId;
+        private String imgId;
         private String deviceName;
         private Double x;
         private Double y;
         private String type;
+        /** 点位图标完整访问 URL */
+        private String imgUrl;
+        /** 绑定的设备详情(含设备类型名称) */
+        private DeviceInfoVo deviceInfo;
+    }
+
+    @Data
+    public static class DeviceInfoVo {
+        private String id;
+        private String deviceId;
+        private Integer channel;
+        /** 设备类型名称(如:视频安防监控) */
+        private String deviceType;
+        private String ipAddr;
+        private Integer port;
+        private String address;
+        private String note;
     }
 }
 

+ 4 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/service/vo/MapPageRequest.java

@@ -9,6 +9,10 @@ public class MapPageRequest {
 
     private Integer size = 10;
 
+    /** 父地图 id,有值时仅查询该父节点下的地图 */
     private String parentId;
+
+    /** 地图 id,有值时仅查询该 id 的地图(可与 parentId 同时使用) */
+    private String mapId;
 }
 

+ 31 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/service/vo/PicAddRequest.java

@@ -0,0 +1,31 @@
+package com.usky.sas.service.vo;
+
+import lombok.Data;
+
+/**
+ * 新增图片请求(不入库二进制文件,仅保存 url/path 及图片资源元数据)
+ */
+@Data
+public class PicAddRequest {
+
+    /** 图片地址(如 /upload/xxx 或完整路径,必填) */
+    private String url;
+
+    /** 图片路径(可选,与 url 拼接或单独存储) */
+    private String path;
+
+    /** 图片名称(写入 sas_pic_source.name) */
+    private String name;
+
+    /** 描述信息(写入 sas_pic_source.remark) */
+    private String remark;
+
+    /** 图片类型(写入 sas_pic_source.pic_type) */
+    private Integer picType;
+
+    /** 子类型(写入 sas_pic_source.subtype) */
+    private Integer subtype;
+
+    /** 标签(写入 sas_pic_source.tag) */
+    private String tag;
+}

+ 25 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/service/vo/PicSourceInfo.java

@@ -0,0 +1,25 @@
+package com.usky.sas.service.vo;
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 图片资源信息(含图片完整访问 URL)
+ */
+@Data
+public class PicSourceInfo {
+
+    private String id;
+    private String name;
+    private String remark;
+    private Integer picType;
+    private Integer subtype;
+    private String tag;
+    private String picId;
+    private LocalDateTime createTime;
+    private LocalDateTime updateTime;
+
+    /** 图片完整访问 URL(协议+主机+端口+pic.url/path) */
+    private String picUrl;
+}

+ 21 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/service/vo/PicSourcePageRequest.java

@@ -0,0 +1,21 @@
+package com.usky.sas.service.vo;
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 图片资源分页请求
+ */
+@Data
+public class PicSourcePageRequest {
+
+    /** 图片类型(可选,对应 sas_pic_source.pic_type) */
+    private Integer picType;
+
+    /** 当前页,默认 1 */
+    private Integer current = 1;
+
+    /** 每页条数,默认 10 */
+    private Integer size = 10;
+}

+ 31 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/service/vo/PicSourceUpdateRequest.java

@@ -0,0 +1,31 @@
+package com.usky.sas.service.vo;
+
+import lombok.Data;
+
+/**
+ * 修改图片资源请求(sas_pic_source + 可选更新关联 sas_pic 的 url/path)
+ */
+@Data
+public class PicSourceUpdateRequest {
+
+    /** 图片名称(sas_pic_source.name) */
+    private String name;
+
+    /** 描述信息(sas_pic_source.remark) */
+    private String remark;
+
+    /** 图片类型(sas_pic_source.pic_type) */
+    private Integer picType;
+
+    /** 子类型(sas_pic_source.subtype) */
+    private Integer subtype;
+
+    /** 标签(sas_pic_source.tag) */
+    private String tag;
+
+    /** 图片地址(可选,传入则更新关联的 sas_pic.url) */
+    private String url;
+
+    /** 图片路径(可选,传入则更新关联的 sas_pic.path) */
+    private String path;
+}