1.增加相机曝光值枚举获取

2.增加地图点位标注
This commit is contained in:
sdy 2026-05-25 17:09:31 +08:00
parent 4cfcbb644f
commit 3177b26cd9
16 changed files with 501 additions and 8 deletions

View File

@ -15,6 +15,7 @@ public interface BusinessConstant {
String REMOTE_LOG_BUCKET = "remote-log";//机库回传媒体桶
String DEVICE_FIRMWARE_BUCKET = "device-firmware";//设备固件桶
String SPEAKER_AUDIO_BUCKET = "speaker-audio";//喊话器音频桶
String GEO_MARK_BUCKET = "geo-mark";//地图标注文件桶
//********************************* route action *********************************//
String DEFAULT_ACTION_TRIGGER_TYPE = "reachPoint";//默认动作触发器类型 到达航点执行

View File

@ -0,0 +1,51 @@
package com.multictrl.common.constant;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum ExposureValue {
// 负曝光值
EV_NEG_5_0("1", "-5.0EV"),
EV_NEG_4_7("2", "-4.7EV"),
EV_NEG_4_3("3", "-4.3EV"),
EV_NEG_4_0("4", "-4.0EV"),
EV_NEG_3_7("5", "-3.7EV"),
EV_NEG_3_3("6", "-3.3EV"),
EV_NEG_3_0("7", "-3.0EV"),
EV_NEG_2_7("8", "-2.7EV"),
EV_NEG_2_3("9", "-2.3EV"),
EV_NEG_2_0("10", "-2.0EV"),
EV_NEG_1_7("11", "-1.7EV"),
EV_NEG_1_3("12", "-1.3EV"),
EV_NEG_1_0("13", "-1.0EV"),
EV_NEG_0_7("14", "-0.7EV"),
EV_NEG_0_3("15", "-0.3EV"),
// 零曝光值
EV_0("16", "0EV"),
// 正曝光值
EV_POS_0_3("17", "0.3EV"),
EV_POS_0_7("18", "0.7EV"),
EV_POS_1_0("19", "1.0EV"),
EV_POS_1_3("20", "1.3EV"),
EV_POS_1_7("21", "1.7EV"),
EV_POS_2_0("22", "2.0EV"),
EV_POS_2_3("23", "2.3EV"),
EV_POS_2_7("24", "2.7EV"),
EV_POS_3_0("25", "3.0EV"),
EV_POS_3_3("26", "3.3EV"),
EV_POS_3_7("27", "3.7EV"),
EV_POS_4_0("28", "4.0EV"),
EV_POS_4_3("29", "4.3EV"),
EV_POS_4_7("30", "4.7EV"),
EV_POS_5_0("31", "5.0EV"),
// 特殊值
FIXED("255", "FIXED");
private final String code;
private final String desc;
}

View File

@ -1,5 +1,6 @@
package com.multictrl.modules.business.controller;
import cn.hutool.json.JSONObject;
import com.multictrl.common.annotation.ApiOrder;
import com.multictrl.common.annotation.LogOperation;
import com.multictrl.common.constant.BusinessConstant;
@ -16,6 +17,7 @@ import lombok.RequiredArgsConstructor;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Objects;
/**
@ -173,8 +175,8 @@ public class CameraController {
@Operation(summary = "相机对焦模式设置", description = "注意: Matrice 30 系列飞行器只支持 zoom 镜头下配置该参数")
@RequiresPermissions("bus:camera:focusModeSet")
public Result<Object> focusModeSet(@PathVariable("dockSn") String dockSn,
@Parameter(name = "mode", description = "对焦模式 1:MF 2:AFS 3:AFC")
@RequestParam Integer mode) {
@Parameter(name = "mode", description = "对焦模式 1:MF 2:AFS 3:AFC")
@RequestParam Integer mode) {
return new Result<>().ok(cameraService.focusModeSet(dockSn, mode));
}
@ -184,8 +186,8 @@ public class CameraController {
@Operation(summary = "相机对焦值设置", description = "注意: Matrice 30 系列飞行器只支持 zoom 镜头下配置该参数")
@RequiresPermissions("bus:camera:focusSet")
public Result<Object> focusSet(@PathVariable("dockSn") String dockSn,
@Parameter(name = "value", description = "对焦值:范围参见飞行器物模型属性 zoom_max_focus_value 和 zoom_min_focus_value")
@RequestParam Integer value) {
@Parameter(name = "value", description = "对焦值:范围参见飞行器物模型属性 zoom_max_focus_value 和 zoom_min_focus_value")
@RequestParam Integer value) {
return new Result<>().ok(cameraService.focusSet(dockSn, value));
}
@ -205,8 +207,8 @@ public class CameraController {
@Operation(summary = "红外测温模式设置", description = "注意: Matrice 30 系列飞行器只支持 zoom 镜头下配置该参数")
@RequiresPermissions("bus:camera:focusSet")
public Result<Object> irMeteringModeSet(@PathVariable("dockSn") String dockSn,
@Parameter(name = "value", description = "对焦值:范围参见飞行器物模型属性 zoom_max_focus_value 和 zoom_min_focus_value")
@RequestParam Integer value) {
@Parameter(name = "value", description = "对焦值:范围参见飞行器物模型属性 zoom_max_focus_value 和 zoom_min_focus_value")
@RequestParam Integer value) {
return new Result<>().ok(cameraService.focusSet(dockSn, value));
}
@ -230,4 +232,11 @@ public class CameraController {
return new Result<>().ok(cameraService.irMeteringAreaSet(dockSn, irMeteringAreaSet));
}
@GetMapping("/getExposureValue")
@Operation(summary = "获取相机曝光值")
public Result<List<JSONObject>> getExposureValue() {
return new Result<List<JSONObject>>().ok(cameraService.getExposureValue());
}
}

View File

@ -0,0 +1,87 @@
package com.multictrl.modules.business.controller;
import com.multictrl.common.annotation.ApiOrder;
import com.multictrl.common.annotation.LogOperation;
import com.multictrl.common.constant.Constant;
import com.multictrl.common.page.PageData;
import com.multictrl.common.utils.Result;
import com.multictrl.common.validator.AssertUtils;
import com.multictrl.common.validator.ValidatorUtils;
import com.multictrl.modules.business.dto.GeoMarkDTO;
import com.multictrl.modules.business.service.GeoMarkService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
/**
* 地图标注
*
* @author Sdy
* @since 1.0.0 2026-05-25
*/
@RestController
@RequestMapping("business/mark")
@Tag(name = "地图标注")
@ApiOrder(12)
@RequiredArgsConstructor
public class GeoMarkController {
private final GeoMarkService geoMarkService;
@GetMapping("page")
@Operation(summary = "分页")
@Parameters({
@Parameter(name = Constant.PAGE, description = "当前页码从1开始"),
@Parameter(name = Constant.LIMIT, description = "每页显示记录数"),
@Parameter(name = "dockSn", description = "设备编号"),
@Parameter(name = "markType", description = "标注类型"),
@Parameter(name = "markName", description = "标注名称"),
@Parameter(name = "showAll", description = "是否展示全局", example = "字符串:true")
})
@RequiresPermissions("bus:mark:page")
public Result<PageData<GeoMarkDTO>> page(@Parameter(hidden = true) @RequestParam Map<String, Object> params) {
PageData<GeoMarkDTO> page = geoMarkService.pageList(params);
return new Result<PageData<GeoMarkDTO>>().ok(page);
}
@GetMapping("{id}")
@Operation(summary = "信息")
@RequiresPermissions("bus:mark:info")
public Result<GeoMarkDTO> get(@PathVariable("id") Long id) {
GeoMarkDTO data = geoMarkService.getDetail(id);
return new Result<GeoMarkDTO>().ok(data);
}
@PostMapping
@Operation(summary = "保存")
@LogOperation("保存")
@RequiresPermissions("bus:mark:save")
public Result<Object> save(@RequestBody GeoMarkDTO dto) {
//效验数据
ValidatorUtils.validateEntity(dto);
geoMarkService.save(dto);
return new Result<>();
}
@DeleteMapping
@Operation(summary = "删除")
@LogOperation("删除")
@RequiresPermissions("bus:mark:delete")
public Result<Object> delete(@RequestBody Long[] ids) {
//效验数据
AssertUtils.isArrayEmpty(ids, "id");
geoMarkService.delete(ids);
return new Result<>();
}
}

View File

@ -44,4 +44,15 @@ public class MinioController {
return new Result<String>().ok(minioService.uploadSpeakerAudio(dockSn, file));
}
@Operation(summary = "上传地图标注文件")
@PostMapping("/uploadGeoMark/{dockSn}")
public Result<String> uploadGeoMark(@PathVariable String dockSn,
@RequestParam("file") MultipartFile file) {
if (file.isEmpty()) {
return new Result<String>().error(ErrorCode.UPLOAD_FILE_EMPTY);
}
return new Result<String>().ok(minioService.uploadGeoMark(dockSn, file));
}
}

View File

@ -0,0 +1,16 @@
package com.multictrl.modules.business.dao;
import com.multictrl.common.dao.BaseDao;
import com.multictrl.modules.business.entity.GeoMarkEntity;
import org.apache.ibatis.annotations.Mapper;
/**
* 地图标注
*
* @author Sdy
* @since 1.0.0 2026-05-25
*/
@Mapper
public interface GeoMarkDao extends BaseDao<GeoMarkEntity> {
}

View File

@ -0,0 +1,72 @@
package com.multictrl.modules.business.dto;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.AssertTrue;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 地图标注
*
* @author Sdy
* @since 1.0.0 2026-05-25
*/
@Data
@Schema(name = "地图标注")
public class GeoMarkDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
@Schema(description = "主键")
private Long id;
@NotBlank(message = "设备编号不能为空")
@Schema(description = "设备编号 ALL为全部")
private String dockSn;
@NotBlank(message = "类型不能为空")
@Schema(description = "类型 {point:点,line:线,polygon:面,circle:圆}")
private String markType;
@NotBlank(message = "标注名称不能为空")
@Schema(description = "标注名称")
private String markName;
@Schema(description = "解释说明")
private String description;
@Schema(description = "颜色")
private String color;
@Schema(description = "页面显示的字体大小")
private String fontSize;
@Schema(description = "图标样式")
private String iconStyle;
@Schema(description = "图标url地址")
private String iconUrl;
@Schema(description = "点位信息集合json格式")
private String pointSet;
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
@Schema(description = "创建时间")
private Date createDate;
@JsonIgnore
@Schema(hidden = true)
@AssertTrue(message = "类型错误")
public boolean isMarkTypeValid() {
return markType.equals("point") || markType.equals("line") || markType.equals("polygon") || markType.equals("circle");
}
}

View File

@ -0,0 +1,72 @@
package com.multictrl.modules.business.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.util.Date;
/**
* 地图标注
*
* @author Sdy
* @since 1.0.0 2026-05-25
*/
@Data
@TableName("bus_geo_mark")
public class GeoMarkEntity {
/**
* 主键
*/
@TableId
private Long id;
/**
* 设备编号 ALL为全部
*/
private String dockSn;
/**
* 类型 / point / line 线 / polygon / circle
*/
private String markType;
/**
* 标注名称
*/
private String markName;
/**
* 解释说明
*/
private String description;
/**
* 颜色
*/
private String color;
/**
* 页面显示的字体大小
*/
private String fontSize;
/**
* 图标样式
*/
private String iconStyle;
/**
* 图标url地址
*/
private String iconUrl;
/**
* 点位信息集合json格式
*/
private String pointSet;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private Date createDate;
/**
* 创建人
*/
@TableField(fill = FieldFill.INSERT)
private String creator;
}

View File

@ -1,7 +1,10 @@
package com.multictrl.modules.business.service;
import cn.hutool.json.JSONObject;
import com.multictrl.modules.business.dto.camera.*;
import java.util.List;
/**
* 云台相机控制
*
@ -60,4 +63,7 @@ public interface CameraService {
//红外测温区域设置
String irMeteringAreaSet(String dockSn, IrMeteringAreaSet irMeteringAreaSet);
//相机曝光值调节
List<JSONObject> getExposureValue();
}

View File

@ -0,0 +1,23 @@
package com.multictrl.modules.business.service;
import com.multictrl.common.page.PageData;
import com.multictrl.common.service.CrudService;
import com.multictrl.modules.business.dto.GeoMarkDTO;
import com.multictrl.modules.business.entity.GeoMarkEntity;
import java.util.Map;
/**
* 地图标注
*
* @author Sdy
* @since 1.0.0 2026-05-25
*/
public interface GeoMarkService extends CrudService<GeoMarkEntity, GeoMarkDTO> {
//分页列表
PageData<GeoMarkDTO> pageList(Map<String, Object> params);
//获取详情
GeoMarkDTO getDetail(Long id);
}

View File

@ -39,4 +39,7 @@ public interface MinioService {
//上传喊话器音频文件
String uploadSpeakerAudio(String dockSn, MultipartFile file);
//上传地图标注文件
String uploadGeoMark(String dockSn, MultipartFile file);
}

View File

@ -2,6 +2,7 @@ package com.multictrl.modules.business.service.impl;
import cn.hutool.json.JSONObject;
import com.multictrl.common.constant.BusinessConstant;
import com.multictrl.common.constant.ExposureValue;
import com.multictrl.common.exception.ErrorCode;
import com.multictrl.common.exception.RenException;
import com.multictrl.common.utils.CacheUtils;
@ -13,6 +14,8 @@ import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
@ -186,6 +189,18 @@ public class CameraServiceImpl implements CameraService {
return djiBaseService.executeAndReturnResult(dockSn, "ir_metering_area_set", data);
}
@Override
public List<JSONObject> getExposureValue() {
List<JSONObject> list = new ArrayList<>();
for (ExposureValue value : ExposureValue.values()) {
JSONObject object = new JSONObject();
object.set("code", value.getCode());
object.set("desc", value.getDesc());
list.add(object);
}
return list;
}
//获取包含payload_index的data
private JSONObject getDataIncludePayloadIndex(String dockSn) {
JSONObject data = new JSONObject();

View File

@ -0,0 +1,68 @@
package com.multictrl.modules.business.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.multictrl.common.constant.BusinessConstant;
import com.multictrl.common.page.PageData;
import com.multictrl.common.service.impl.CrudServiceImpl;
import com.multictrl.modules.business.dao.GeoMarkDao;
import com.multictrl.modules.business.dto.GeoMarkDTO;
import com.multictrl.modules.business.entity.GeoMarkEntity;
import cn.hutool.core.util.StrUtil;
import com.multictrl.modules.business.service.GeoMarkService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.Map;
/**
* 地图标注
*
* @author Sdy
* @since 1.0.0 2026-05-25
*/
@Service
@RequiredArgsConstructor
public class GeoMarkServiceImpl extends CrudServiceImpl<GeoMarkDao, GeoMarkEntity, GeoMarkDTO> implements GeoMarkService {
@Override
public QueryWrapper<GeoMarkEntity> getWrapper(Map<String, Object> params) {
String id = (String) params.get("id");
String dockSn = (String) params.get("dockSn");
String markType = (String) params.get("markType");
String markName = (String) params.get("markName");
String showAll = (String) params.get("showAll");
QueryWrapper<GeoMarkEntity> wrapper = new QueryWrapper<>();
wrapper.eq(StrUtil.isNotBlank(id), "id", id);
wrapper.and(StrUtil.isNotBlank(dockSn), v ->
v.eq("dock_sn", dockSn).or(StrUtil.isNotBlank(showAll) && "true".equals(showAll),
vv -> vv.eq("dock_sn", "ALL")));
wrapper.eq(StrUtil.isNotBlank(markType), "mark_type", markType);
wrapper.like(StrUtil.isNotBlank(markName), "mark_name", markName);
wrapper.orderByDesc("create_date");
return wrapper;
}
@Override
public PageData<GeoMarkDTO> pageList(Map<String, Object> params) {
PageData<GeoMarkDTO> page = page(params);
for (GeoMarkDTO geoMarkDTO : page.getList()) {
String iconUrl = geoMarkDTO.getIconUrl();
if (StrUtil.isNotBlank(iconUrl)) {
geoMarkDTO.setIconUrl(BusinessConstant.IMAGE_PATH + iconUrl);
}
}
return page;
}
@Override
public GeoMarkDTO getDetail(Long id) {
GeoMarkDTO geoMarkDTO = get(id);
if (geoMarkDTO != null) {
String iconUrl = geoMarkDTO.getIconUrl();
geoMarkDTO.setIconUrl(BusinessConstant.IMAGE_PATH + iconUrl);
}
return geoMarkDTO;
}
}

View File

@ -183,6 +183,20 @@ public class MinioServiceImpl implements MinioService {
return BusinessConstant.SPEAKER_AUDIO_BUCKET + "/" + path;
}
@Override
public String uploadGeoMark(String dockSn, MultipartFile file) {
//文件路径
String path = dockSn + "/" + DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN_COMPACT) + "." + FileNameUtil.extName(file.getOriginalFilename());
try {
uploadFile(file.getInputStream(), BusinessConstant.GEO_MARK_BUCKET, path);
} catch (Exception e) {
log.error(ExceptionUtils.getErrorStackTrace(e));
throw new RenException(ErrorCode.OSS_UPLOAD_FILE_ERROR, file.getOriginalFilename());
}
return BusinessConstant.GEO_MARK_BUCKET + "/" + path;
}
private String getMimeType(String fileName) {
if (fileName == null) return "application/octet-stream";

View File

@ -31,7 +31,7 @@ public class PasswordUtils {
public static void main(String[] args) {
String str = "admin";
String str = "MultiAdmin2023!";
String password = encode(str);
System.out.println(password);

View File

@ -2027,3 +2027,48 @@ INSERT INTO "public"."bus_device_dic"
VALUES (41, 1, 99, 0, 'M4TD Camera', NULL);
INSERT INTO "public"."bus_device_dic"
VALUES (42, 3, 3, 0, 'Dock3', NULL);
--2026/5/25
DROP TABLE IF EXISTS "public"."bus_geo_mark";
CREATE TABLE "public"."bus_geo_mark"
(
"id" int8 NOT NULL,
"dock_sn" varchar(64) COLLATE "pg_catalog"."default" NOT NULL,
"mark_type" varchar(64) COLLATE "pg_catalog"."default" NOT NULL,
"mark_name" varchar(128) COLLATE "pg_catalog"."default" NOT NULL,
"description" varchar(256) COLLATE "pg_catalog"."default",
"color" varchar(64) COLLATE "pg_catalog"."default",
"font_size" varchar(16) COLLATE "pg_catalog"."default",
"icon_style" varchar(64) COLLATE "pg_catalog"."default",
"icon_url" varchar(256) COLLATE "pg_catalog"."default",
"point_set" text COLLATE "pg_catalog"."default",
"create_date" timestamp(6),
"creator" varchar(64) COLLATE "pg_catalog"."default"
)
;
COMMENT
ON COLUMN "public"."bus_geo_mark"."id" IS '主键';
COMMENT
ON COLUMN "public"."bus_geo_mark"."dock_sn" IS '设备编号 ALL为全部';
COMMENT
ON COLUMN "public"."bus_geo_mark"."mark_type" IS '类型 / point 点 / line 线 / polygon 面 / circle 圆';
COMMENT
ON COLUMN "public"."bus_geo_mark"."mark_name" IS '标注名称';
COMMENT
ON COLUMN "public"."bus_geo_mark"."description" IS '简介描述';
COMMENT
ON COLUMN "public"."bus_geo_mark"."color" IS '颜色';
COMMENT
ON COLUMN "public"."bus_geo_mark"."font_size" IS '字体大小';
COMMENT
ON COLUMN "public"."bus_geo_mark"."icon_style" IS '图标样式';
COMMENT
ON COLUMN "public"."bus_geo_mark"."icon_url" IS '图标url地址';
COMMENT
ON COLUMN "public"."bus_geo_mark"."point_set" IS '点位信息集合json格式';
COMMENT
ON COLUMN "public"."bus_geo_mark"."create_date" IS '创建时间';
COMMENT
ON COLUMN "public"."bus_geo_mark"."creator" IS '创建人';
COMMENT
ON TABLE "public"."bus_geo_mark" IS '地图标注';