diff --git a/core/pom.xml b/core/pom.xml
index 94afd03..a1e8bba 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -10,6 +10,10 @@
core
1.0.0-SNAPSHOT
+
+ UTF-8
+
+
org.springframework.boot
@@ -161,6 +165,38 @@
opencv
4.7.0-0
+
+
+
+ org.springframework.boot
+ spring-boot-starter-mail
+
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+
+
+ com.aliyun
+ aliyun-java-sdk-core
+ 4.6.3
+
+
+
+
+ com.aliyun
+ aliyun-java-sdk-dysmsapi
+ 2.1.0
+
+
+
+
+ javax.xml.bind
+ jaxb-api
+ 2.3.1
+
diff --git a/core/src/main/java/com/dite/znpt/domain/dto/FolderDto.java b/core/src/main/java/com/dite/znpt/domain/dto/FolderDto.java
index d4c5f8e..a91faff 100644
--- a/core/src/main/java/com/dite/znpt/domain/dto/FolderDto.java
+++ b/core/src/main/java/com/dite/znpt/domain/dto/FolderDto.java
@@ -1,15 +1,15 @@
-package com.dite.znpt.domain.dto;
-
-import io.swagger.annotations.ApiModel;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-@Data
-@AllArgsConstructor
-@NoArgsConstructor
-@ApiModel("接受文件夹参数")
-public class FolderDto {
- private String name = "tom";
- private Long parentId = 0L;
-}
+package com.dite.znpt.domain.dto;
+
+import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@ApiModel("接受文件夹参数")
+public class FolderDto {
+ private String name = "tom";
+ private Long parentId = 0L;
+}
diff --git a/core/src/main/java/com/dite/znpt/domain/entity/BusinessDataEntity.java b/core/src/main/java/com/dite/znpt/domain/entity/BusinessDataEntity.java
index 4b88a8e..3bd598e 100644
--- a/core/src/main/java/com/dite/znpt/domain/entity/BusinessDataEntity.java
+++ b/core/src/main/java/com/dite/znpt/domain/entity/BusinessDataEntity.java
@@ -1,38 +1,38 @@
-package com.dite.znpt.domain.entity;
-
-
-import com.baomidou.mybatisplus.annotation.TableName;
-import io.swagger.annotations.ApiModel;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.NoArgsConstructor;
-
-import java.time.LocalDateTime;
-
-@Data
-@EqualsAndHashCode(callSuper = false)
-@TableName("business_data_part")
-@ApiModel(value="商务资料文件夹对象")
-@AllArgsConstructor
-@NoArgsConstructor
-public class BusinessDataEntity {
-
- // 主键
- private Long folderId = null;
- // 文件夹名称
- private String folderName = null;
- // 父级文件夹
- private Long parentId = null;
- // 创建人
- private Long creatorId = null;
- // 创建时间
- private LocalDateTime createTime = null;
- // 更新时间
- private LocalDateTime updateTime = null;
- // 是否删除
- private Boolean isDeleted = false;
- // 文件夹路径
- private String folderPath = null;
-
-}
+package com.dite.znpt.domain.entity;
+
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDateTime;
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("business_data_part")
+@ApiModel(value="商务资料文件夹对象")
+@AllArgsConstructor
+@NoArgsConstructor
+public class BusinessDataEntity {
+
+ // 主键
+ private Long folderId = null;
+ // 文件夹名称
+ private String folderName = null;
+ // 父级文件夹
+ private Long parentId = null;
+ // 创建人
+ private Long creatorId = null;
+ // 创建时间
+ private LocalDateTime createTime = null;
+ // 更新时间
+ private LocalDateTime updateTime = null;
+ // 是否删除
+ private Boolean isDeleted = false;
+ // 文件夹路径
+ private String folderPath = null;
+
+}
diff --git a/core/src/main/java/com/dite/znpt/domain/entity/BusinessDataFileEntity.java b/core/src/main/java/com/dite/znpt/domain/entity/BusinessDataFileEntity.java
index c9c589d..6b14ed8 100644
--- a/core/src/main/java/com/dite/znpt/domain/entity/BusinessDataFileEntity.java
+++ b/core/src/main/java/com/dite/znpt/domain/entity/BusinessDataFileEntity.java
@@ -1,37 +1,37 @@
-package com.dite.znpt.domain.entity;
-
-
-import com.baomidou.mybatisplus.annotation.TableName;
-import io.swagger.annotations.ApiModel;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-import java.util.Date;
-
-@Data
-@EqualsAndHashCode(callSuper = false)
-@TableName("business_data_part_file")
-@ApiModel(value="商务资料对象")
-
-public class BusinessDataFileEntity {
-
- //文件id
- private Long fileId = null;
- //文件夹id
- private Long folderId = null;
- //文件名
- private String fileName = null;
- //文件路径
- private String filePath = null;
- //文件类型
- private String fileType = "unknown";
- //文件大小
- private Long fileSize = null;
- //上传时间
- private Date uploadTime = null;
- //上传人id
- private Long uploaderId = null;
- //是否删除
- private Boolean isDeleted = false;
-
-}
+package com.dite.znpt.domain.entity;
+
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("business_data_part_file")
+@ApiModel(value="商务资料对象")
+
+public class BusinessDataFileEntity {
+
+ //文件id
+ private Long fileId = null;
+ //文件夹id
+ private Long folderId = null;
+ //文件名
+ private String fileName = null;
+ //文件路径
+ private String filePath = null;
+ //文件类型
+ private String fileType = "unknown";
+ //文件大小
+ private Long fileSize = null;
+ //上传时间
+ private Date uploadTime = null;
+ //上传人id
+ private Long uploaderId = null;
+ //是否删除
+ private Boolean isDeleted = false;
+
+}
diff --git a/core/src/main/java/com/dite/znpt/domain/entity/EquipmentEntity.java b/core/src/main/java/com/dite/znpt/domain/entity/EquipmentEntity.java
index 84a6ea2..4224af2 100644
--- a/core/src/main/java/com/dite/znpt/domain/entity/EquipmentEntity.java
+++ b/core/src/main/java/com/dite/znpt/domain/entity/EquipmentEntity.java
@@ -1,218 +1,217 @@
-package com.dite.znpt.domain.entity;
-
-import com.baomidou.mybatisplus.annotation.*;
-import com.dite.znpt.domain.AuditableEntity;
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.math.BigDecimal;
-import java.time.LocalDateTime;
-
-/**
- * @author Bear.G
- * @date 2025/7/23/周三 17:26
- * @description
- */
-@Data
-@EqualsAndHashCode(callSuper = false)
-@TableName("equipment")
-@ApiModel(value="EquipmentEntity对象", description="设备信息表")
-public class EquipmentEntity extends AuditableEntity implements Serializable {
- private static final long serialVersionUID = -6665040704562461286L;
-
- @ApiModelProperty("设备id")
- @TableId(type = IdType.ASSIGN_ID)
- private String equipmentId;
-
- @ApiModelProperty("资产编号")
- private String assetCode;
-
- @ApiModelProperty("设备名称")
- private String equipmentName;
-
- @ApiModelProperty("设备型号")
- private String equipmentModel;
-
- @ApiModelProperty("设备类型")
- private String equipmentType;
-
- @ApiModelProperty("设备状态,枚举:EquipmentStatusEnum")
- private String equipmentStatus;
-
- @ApiModelProperty("使用状态,0-空闲中,1-使用中")
- private String useStatus;
-
- @ApiModelProperty("设备序列号")
- private String equipmentSn;
-
- @ApiModelProperty("品牌")
- private String brand;
-
- @ApiModelProperty("配置规格/参数")
- private String specification;
-
- @ApiModelProperty("位置状态")
- private String locationStatus;
-
- @ApiModelProperty("设备当前物理位置")
- private String physicalLocation;
-
- @ApiModelProperty("负责人")
- private String responsiblePerson;
-
- @ApiModelProperty("健康状态")
- private String healthStatus;
-
- @ApiModelProperty("采购时间")
- private LocalDateTime purchaseTime;
-
- @ApiModelProperty("入库时间")
- private LocalDateTime inStockTime;
-
- @ApiModelProperty("启用时间")
- private LocalDateTime activationTime;
-
- @ApiModelProperty("预计报废时间")
- private LocalDateTime expectedScrapTime;
-
- @ApiModelProperty("实际报废时间")
- private LocalDateTime actualScrapTime;
-
- @ApiModelProperty("状态变更时间")
- private LocalDateTime statusChangeTime;
-
- @ApiModelProperty("采购订单")
- private String purchaseOrder;
-
- @ApiModelProperty("供应商名称")
- private String supplierName;
-
- // 移除采购价格字段,使用单价和总价替代
- // @ApiModelProperty("采购价格")
- // private BigDecimal purchasePrice;
-
- @ApiModelProperty("当前净值")
- private BigDecimal currentNetValue;
-
- @ApiModelProperty("折旧方法")
- private String depreciationMethod;
-
- @ApiModelProperty("折旧年限")
- private Integer depreciationYears;
-
- @ApiModelProperty("残值")
- private BigDecimal salvageValue;
-
- @ApiModelProperty("保修截止日期")
- private LocalDateTime warrantyExpireDate;
-
- @ApiModelProperty("上次维护日期")
- private LocalDateTime lastMaintenanceDate;
-
- @ApiModelProperty("下次维护日期")
- private LocalDateTime nextMaintenanceDate;
-
- @ApiModelProperty("维护人员")
- private String maintenancePerson;
-
- @ApiModelProperty("库存条码")
- private String inventoryBarcode;
-
- @ApiModelProperty("资产备注")
- private String assetRemark;
-
- @ApiModelProperty("次户号")
- private String accountNumber;
-
- @ApiModelProperty("数量")
- private Integer quantity;
-
- @ApiModelProperty("单价")
- private BigDecimal unitPrice;
-
- @ApiModelProperty("总价")
- private BigDecimal totalPrice;
-
- // 移除备用状态字段,使用现有的 location_status 字段
- // @ApiModelProperty("备用状态")
- // private String spareStatus;
-
- @ApiModelProperty("盘点依据")
- private String inventoryBasis;
-
- @ApiModelProperty("动态记录")
- private String dynamicRecord;
-
- // 移除认证状态字段,使用现有的 health_status 字段
- // @ApiModelProperty("认证状态")
- // private String certificationStatus;
-
- @ApiModelProperty("使用部门/人")
- private String usingDepartment;
-
- @ApiModelProperty("领用时间")
- private LocalDateTime borrowingTime;
-
- @ApiModelProperty("归还时间")
- private LocalDateTime returnTime;
-
- @ApiModelProperty("出库时间")
- private LocalDateTime outStockTime;
-
- @ApiModelProperty("总使用时间")
- private String totalUsageTime;
-
- @ApiModelProperty("折旧率")
- private BigDecimal depreciationRate;
-
- @ApiModelProperty("折旧方法说明")
- private String depreciationMethodDesc;
-
- @ApiModelProperty("发票")
- private String invoice;
-
- @ApiModelProperty("发票状态")
- private String invoiceStatus;
-
- @ApiModelProperty("附件")
- private String attachments;
-
- @ApiModelProperty("照片")
- private String photos;
-
- @ApiModelProperty("条码")
- private String barcode;
-
- @ApiModelProperty("导入人")
- private String importer;
-
- @ApiModelProperty("盘库时间/状态1")
- private String inventoryTimeStatus1;
-
- @ApiModelProperty("盘库时间/状态2")
- private String inventoryTimeStatus2;
-
- @ApiModelProperty("盘库时间/状态3")
- private String inventoryTimeStatus3;
-
- @ApiModelProperty("盘点时间/状态1")
- private String inventoryCheckTimeStatus1;
-
- @ApiModelProperty("盘点时间/状态2")
- private String inventoryCheckTimeStatus2;
-
- @ApiModelProperty("盘点时间/状态3")
- private String inventoryCheckTimeStatus3;
-
- @ApiModelProperty("当前使用记录id")
- @TableField(updateStrategy = FieldStrategy.ALWAYS)
- private String useRecordId;
-
- @ApiModelProperty("删除标志(0代表存在 1代表删除)")
- @TableLogic(value = "0", delval = "1")
- private String delFlag;
-}
+package com.dite.znpt.domain.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.dite.znpt.domain.AuditableEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * @author Bear.G
+ * @date 2025/7/23/周三 17:26
+ * @description
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("equipment")
+@ApiModel(value="EquipmentEntity对象", description="设备信息表")
+public class EquipmentEntity extends AuditableEntity implements Serializable {
+ private static final long serialVersionUID = -6665040704562461286L;
+
+ @ApiModelProperty("设备id")
+ @TableId(type = IdType.ASSIGN_ID)
+ private String equipmentId;
+
+ @ApiModelProperty("资产编号")
+ private String assetCode;
+
+ @ApiModelProperty("设备名称")
+ private String equipmentName;
+
+ @ApiModelProperty("设备型号")
+ private String equipmentModel;
+
+ @ApiModelProperty("设备类型")
+ private String equipmentType;
+
+ @ApiModelProperty("设备状态,枚举:EquipmentStatusEnum")
+ private String equipmentStatus;
+
+ @ApiModelProperty("使用状态,0-空闲中,1-使用中")
+ private String useStatus;
+
+ @ApiModelProperty("设备序列号")
+ private String equipmentSn;
+
+ @ApiModelProperty("品牌")
+ private String brand;
+
+ @ApiModelProperty("配置规格/参数")
+ private String specification;
+
+ @ApiModelProperty("位置状态")
+ private String locationStatus;
+
+ @ApiModelProperty("设备当前物理位置")
+ private String physicalLocation;
+
+ @ApiModelProperty("负责人")
+ private String responsiblePerson;
+
+ @ApiModelProperty("健康状态")
+ private String healthStatus;
+
+ @ApiModelProperty("采购时间")
+ private LocalDateTime purchaseTime;
+
+ @ApiModelProperty("入库时间")
+ private LocalDateTime inStockTime;
+
+ @ApiModelProperty("启用时间")
+ private LocalDateTime activationTime;
+
+ @ApiModelProperty("预计报废时间")
+ private LocalDateTime expectedScrapTime;
+
+ @ApiModelProperty("实际报废时间")
+ private LocalDateTime actualScrapTime;
+
+ @ApiModelProperty("状态变更时间")
+ private LocalDateTime statusChangeTime;
+
+ @ApiModelProperty("采购订单")
+ private String purchaseOrder;
+
+ @ApiModelProperty("供应商名称")
+ private String supplierName;
+
+ // 移除采购价格字段,使用单价和总价替代
+ // @ApiModelProperty("采购价格")
+ // private BigDecimal purchasePrice;
+
+ @ApiModelProperty("当前净值")
+ private BigDecimal currentNetValue;
+
+ @ApiModelProperty("折旧方法")
+ private String depreciationMethod;
+
+ @ApiModelProperty("折旧年限")
+ private Integer depreciationYears;
+
+ @ApiModelProperty("残值")
+ private BigDecimal salvageValue;
+
+ @ApiModelProperty("保修截止日期")
+ private LocalDateTime warrantyExpireDate;
+
+ @ApiModelProperty("上次维护日期")
+ private LocalDateTime lastMaintenanceDate;
+
+ @ApiModelProperty("下次维护日期")
+ private LocalDateTime nextMaintenanceDate;
+
+ @ApiModelProperty("维护人员")
+ private String maintenancePerson;
+
+ @ApiModelProperty("库存条码")
+ private String inventoryBarcode;
+
+ @ApiModelProperty("资产备注")
+ private String assetRemark;
+
+ @ApiModelProperty("次户号")
+ private String accountNumber;
+
+ @ApiModelProperty("数量")
+ private Integer quantity;
+
+ @ApiModelProperty("单价")
+ private BigDecimal unitPrice;
+
+ @ApiModelProperty("总价")
+ private BigDecimal totalPrice;
+
+ // 移除备用状态字段,使用现有的 location_status 字段
+ // @ApiModelProperty("备用状态")
+ // private String spareStatus;
+
+ @ApiModelProperty("盘点依据")
+ private String inventoryBasis;
+
+ @ApiModelProperty("动态记录")
+ private String dynamicRecord;
+
+ // 移除认证状态字段,使用现有的 health_status 字段
+ // @ApiModelProperty("认证状态")
+ // private String certificationStatus;
+
+ @ApiModelProperty("使用部门/人")
+ private String usingDepartment;
+
+ @ApiModelProperty("领用时间")
+ private LocalDateTime borrowingTime;
+
+ @ApiModelProperty("归还时间")
+ private LocalDateTime returnTime;
+
+ @ApiModelProperty("出库时间")
+ private LocalDateTime outStockTime;
+
+ @ApiModelProperty("总使用时间")
+ private String totalUsageTime;
+
+ @ApiModelProperty("折旧率")
+ private BigDecimal depreciationRate;
+
+ @ApiModelProperty("折旧方法说明")
+ private String depreciationMethodDesc;
+
+ @ApiModelProperty("发票")
+ private String invoice;
+
+ @ApiModelProperty("发票状态")
+ private String invoiceStatus;
+
+ @ApiModelProperty("附件")
+ private String attachments;
+
+ @ApiModelProperty("照片")
+ private String photos;
+
+ @ApiModelProperty("条码")
+ private String barcode;
+
+ @ApiModelProperty("导入人")
+ private String importer;
+
+ @ApiModelProperty("盘库时间/状态1")
+ private String inventoryTimeStatus1;
+
+ @ApiModelProperty("盘库时间/状态2")
+ private String inventoryTimeStatus2;
+
+ @ApiModelProperty("盘库时间/状态3")
+ private String inventoryTimeStatus3;
+
+ @ApiModelProperty("盘点时间/状态1")
+ private String inventoryCheckTimeStatus1;
+
+ @ApiModelProperty("盘点时间/状态2")
+ private String inventoryCheckTimeStatus2;
+
+ @ApiModelProperty("盘点时间/状态3")
+ private String inventoryCheckTimeStatus3;
+
+ @ApiModelProperty("当前使用记录id")
+ @TableField(updateStrategy = FieldStrategy.ALWAYS)
+ private String useRecordId;
+
+ @ApiModelProperty("删除标志(0代表存在 1代表删除)")
+ @TableLogic(value = "0", delval = "1")
+ private String delFlag;
+}
diff --git a/core/src/main/java/com/dite/znpt/domain/entity/PostEntity.java b/core/src/main/java/com/dite/znpt/domain/entity/PostEntity.java
index 6bb6771..dcfcdb9 100644
--- a/core/src/main/java/com/dite/znpt/domain/entity/PostEntity.java
+++ b/core/src/main/java/com/dite/znpt/domain/entity/PostEntity.java
@@ -1,6 +1,5 @@
package com.dite.znpt.domain.entity;
-import com.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
diff --git a/core/src/main/java/com/dite/znpt/domain/entity/RegulationEntity.java b/core/src/main/java/com/dite/znpt/domain/entity/RegulationEntity.java
index b7e4845..e3519a0 100644
--- a/core/src/main/java/com/dite/znpt/domain/entity/RegulationEntity.java
+++ b/core/src/main/java/com/dite/znpt/domain/entity/RegulationEntity.java
@@ -1,12 +1,15 @@
package com.dite.znpt.domain.entity;
-import com.baomidou.mybatisplus.annotation.*;
+import com.alibaba.excel.annotation.ExcelProperty;
+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 com.dite.znpt.domain.AuditableEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
-import com.alibaba.excel.annotation.ExcelProperty;
import java.io.Serializable;
import java.time.LocalDateTime;
diff --git a/core/src/main/java/com/dite/znpt/domain/page/PageBean.java b/core/src/main/java/com/dite/znpt/domain/page/PageBean.java
index e28d250..5a2992b 100644
--- a/core/src/main/java/com/dite/znpt/domain/page/PageBean.java
+++ b/core/src/main/java/com/dite/znpt/domain/page/PageBean.java
@@ -1,16 +1,15 @@
-package com.dite.znpt.domain.page;
-
-import io.swagger.annotations.ApiOperation;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.util.List;
-
-@Data
-@NoArgsConstructor
-@AllArgsConstructor
-public class PageBean {
- private Long total;
- private List> rows;
-}
+package com.dite.znpt.domain.page;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class PageBean {
+ private Long total;
+ private List> rows;
+}
diff --git a/core/src/main/java/com/dite/znpt/domain/vo/ContractListReq.java b/core/src/main/java/com/dite/znpt/domain/vo/ContractListReq.java
index fa58191..facfb38 100644
--- a/core/src/main/java/com/dite/znpt/domain/vo/ContractListReq.java
+++ b/core/src/main/java/com/dite/znpt/domain/vo/ContractListReq.java
@@ -7,7 +7,6 @@ import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
-import java.util.Date;
/**
* @author huise23
@@ -42,9 +41,6 @@ public class ContractListReq implements Serializable {
@ApiModelProperty("部门id")
private String departmentId;
- @ApiModelProperty("签订日期")
- private Date signDate;
-
@ApiModelProperty("期限")
private String duration;
@@ -54,12 +50,6 @@ public class ContractListReq implements Serializable {
@ApiModelProperty("产品或服务")
private String productService;
- @ApiModelProperty("付款日期/交付日期")
- private Date paymentDate;
-
- @ApiModelProperty("履约时间期限")
- private Date performanceDeadline;
-
@ApiModelProperty("付款地址/交付地址")
private String paymentAddress;
diff --git a/core/src/main/java/com/dite/znpt/domain/vo/ContractResp.java b/core/src/main/java/com/dite/znpt/domain/vo/ContractResp.java
index f21e2ca..a1f4ff0 100644
--- a/core/src/main/java/com/dite/znpt/domain/vo/ContractResp.java
+++ b/core/src/main/java/com/dite/znpt/domain/vo/ContractResp.java
@@ -1,15 +1,12 @@
package com.dite.znpt.domain.vo;
-import java.math.BigDecimal;
-import java.util.Date;
-
-import com.alibaba.excel.annotation.ExcelProperty;
-import com.baomidou.mybatisplus.annotation.TableField;
+import com.dite.znpt.domain.entity.ContractEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
-import com.dite.znpt.domain.entity.ContractEntity;
+
+import java.math.BigDecimal;
/**
* @author huise23
@@ -35,5 +32,8 @@ public class ContractResp extends ContractEntity {
@ApiModelProperty("已收款金额")
private BigDecimal receivedAmount;
+
+ @ApiModelProperty("合同状态名称")
+ private String contractStatusLabel;
}
diff --git a/core/src/main/java/com/dite/znpt/domain/vo/ProjectBudgetInfoDetailResp.java b/core/src/main/java/com/dite/znpt/domain/vo/ProjectBudgetInfoDetailResp.java
index fa1b3df..1216dcc 100644
--- a/core/src/main/java/com/dite/znpt/domain/vo/ProjectBudgetInfoDetailResp.java
+++ b/core/src/main/java/com/dite/znpt/domain/vo/ProjectBudgetInfoDetailResp.java
@@ -1,58 +1,57 @@
-package com.dite.znpt.domain.vo;
-
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-import io.swagger.annotations.ApiOperation;
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-
-@Data
-@ApiModel("项目预算信息详情")
-public class ProjectBudgetInfoDetailResp implements Serializable {
- @Serial
- private static final long serialVersionUID = 766154886845694269L;
-
- @ApiModelProperty("项目id")
- private String projectId;
-
- @ApiModelProperty("项目名称")
- private String projectName;
-
- @ApiModelProperty("项目预算")
- private Double projectBudget;
-
- @ApiModelProperty("人工成本")
- private Double laborCost;
-
- @ApiModelProperty("设备摊销")
- private Double equipmentAmortization;
-
- @ApiModelProperty("奖金预提")
- private Double bonusProvision;
-
- @ApiModelProperty("交通食宿")
- private Double transAccomMeals;
-
- @ApiModelProperty("其他杂费")
- private Double othersCost;
-
- @ApiModelProperty("已用人工成本")
- private Double useLaborCost;
-
- @ApiModelProperty("已用设备摊销")
- private Double useEquipmentAmortization;
-
- @ApiModelProperty("已用奖金预提")
- private Double useBonusProvision;
-
- @ApiModelProperty("已用交通食宿")
- private Double useTransAccomMeals;
-
- @ApiModelProperty("已用其他杂费")
- private Double useOthersCost;
-
- @ApiModelProperty("剩余预算")
- private Double restBudget;
-}
+package com.dite.znpt.domain.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+@Data
+@ApiModel("项目预算信息详情")
+public class ProjectBudgetInfoDetailResp implements Serializable {
+ @Serial
+ private static final long serialVersionUID = 766154886845694269L;
+
+ @ApiModelProperty("项目id")
+ private String projectId;
+
+ @ApiModelProperty("项目名称")
+ private String projectName;
+
+ @ApiModelProperty("项目预算")
+ private Double projectBudget;
+
+ @ApiModelProperty("人工成本")
+ private Double laborCost;
+
+ @ApiModelProperty("设备摊销")
+ private Double equipmentAmortization;
+
+ @ApiModelProperty("奖金预提")
+ private Double bonusProvision;
+
+ @ApiModelProperty("交通食宿")
+ private Double transAccomMeals;
+
+ @ApiModelProperty("其他杂费")
+ private Double othersCost;
+
+ @ApiModelProperty("已用人工成本")
+ private Double useLaborCost;
+
+ @ApiModelProperty("已用设备摊销")
+ private Double useEquipmentAmortization;
+
+ @ApiModelProperty("已用奖金预提")
+ private Double useBonusProvision;
+
+ @ApiModelProperty("已用交通食宿")
+ private Double useTransAccomMeals;
+
+ @ApiModelProperty("已用其他杂费")
+ private Double useOthersCost;
+
+ @ApiModelProperty("剩余预算")
+ private Double restBudget;
+}
diff --git a/core/src/main/java/com/dite/znpt/domain/vo/ProjectListReq.java b/core/src/main/java/com/dite/znpt/domain/vo/ProjectListReq.java
index 9ba2992..02b087c 100644
--- a/core/src/main/java/com/dite/znpt/domain/vo/ProjectListReq.java
+++ b/core/src/main/java/com/dite/znpt/domain/vo/ProjectListReq.java
@@ -1,7 +1,5 @@
package com.dite.znpt.domain.vo;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
diff --git a/core/src/main/java/com/dite/znpt/domain/vo/ProjectListResp.java b/core/src/main/java/com/dite/znpt/domain/vo/ProjectListResp.java
index cd29090..61faa9b 100644
--- a/core/src/main/java/com/dite/znpt/domain/vo/ProjectListResp.java
+++ b/core/src/main/java/com/dite/znpt/domain/vo/ProjectListResp.java
@@ -1,10 +1,5 @@
package com.dite.znpt.domain.vo;
-import com.alibaba.excel.annotation.ExcelProperty;
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -12,7 +7,6 @@ import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDate;
-import java.time.LocalDateTime;
/**
* @Author: gaoxiong
diff --git a/core/src/main/java/com/dite/znpt/domain/vo/ProjectReq.java b/core/src/main/java/com/dite/znpt/domain/vo/ProjectReq.java
index 2246c57..5fdcc16 100644
--- a/core/src/main/java/com/dite/znpt/domain/vo/ProjectReq.java
+++ b/core/src/main/java/com/dite/znpt/domain/vo/ProjectReq.java
@@ -1,6 +1,5 @@
package com.dite.znpt.domain.vo;
-import com.alibaba.excel.annotation.ExcelProperty;
import com.dite.znpt.util.ValidationGroup;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
diff --git a/core/src/main/java/com/dite/znpt/domain/vo/ProjectResp.java b/core/src/main/java/com/dite/znpt/domain/vo/ProjectResp.java
index 055af72..16eb289 100644
--- a/core/src/main/java/com/dite/znpt/domain/vo/ProjectResp.java
+++ b/core/src/main/java/com/dite/znpt/domain/vo/ProjectResp.java
@@ -1,19 +1,11 @@
package com.dite.znpt.domain.vo;
-import com.alibaba.excel.annotation.ExcelProperty;
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
-import lombok.EqualsAndHashCode;
-import com.dite.znpt.domain.entity.ProjectEntity;
import java.io.Serial;
import java.io.Serializable;
-import java.time.LocalDate;
/**
* @author huise23
diff --git a/core/src/main/java/com/dite/znpt/enums/ContractStatusEnum.java b/core/src/main/java/com/dite/znpt/enums/ContractStatusEnum.java
new file mode 100644
index 0000000..0ba6bc0
--- /dev/null
+++ b/core/src/main/java/com/dite/znpt/enums/ContractStatusEnum.java
@@ -0,0 +1,54 @@
+package com.dite.znpt.enums;
+
+import cn.hutool.json.JSONObject;
+import lombok.Getter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Bear.G
+ * @date 2025/5/27/周二 15:33
+ * @description
+ */
+@Getter
+public enum ContractStatusEnum {
+
+ UN_APPROVAL("UN_APPROVAL", "待审批"),
+ UN_SETTLED("UN_SETTLED", "待结算"),
+ UN_PAY("UN_PAY", "待收款"),
+ COMPLETE("COMPLETE", "已完成"),
+ ;
+
+ private final String code;
+ private final String desc;
+
+ ContractStatusEnum(String code, String desc){
+ this.code = code;
+ this.desc = desc;
+ }
+
+ public static ContractStatusEnum getByCode(String code){
+ for (ContractStatusEnum e : ContractStatusEnum.values() ) {
+ if(e.code.equals(code)){
+ return e;
+ }
+ }
+ return null;
+ }
+
+ public static String getDescByCode(String code){
+ ContractStatusEnum e = getByCode(code);
+ return null == e ? null : e.desc;
+ }
+
+ public static List listAll(){
+ List list = new ArrayList<>(ContractStatusEnum.values().length);
+ for (ContractStatusEnum e : ContractStatusEnum.values() ) {
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.set(e.code, e.desc);
+ list.add(jsonObject);
+ }
+ return list;
+ }
+}
diff --git a/core/src/main/java/com/dite/znpt/enums/HealthStatusEnum.java b/core/src/main/java/com/dite/znpt/enums/HealthStatusEnum.java
index 53521ab..7b437d9 100644
--- a/core/src/main/java/com/dite/znpt/enums/HealthStatusEnum.java
+++ b/core/src/main/java/com/dite/znpt/enums/HealthStatusEnum.java
@@ -1,53 +1,53 @@
-package com.dite.znpt.enums;
-
-import cn.hutool.json.JSONObject;
-import lombok.Getter;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author Bear.G
- * @date 2025/7/31/周四 15:30
- * @description 设备健康状态枚举
- */
-@Getter
-public enum HealthStatusEnum {
- EXCELLENT("excellent", "优秀"),
- GOOD("good", "良好"),
- NORMAL("normal", "一般"),
- POOR("poor", "较差"),
- BAD("bad", "差");
-
- private final String code;
- private final String desc;
-
- HealthStatusEnum(String code, String desc) {
- this.code = code;
- this.desc = desc;
- }
-
- public static HealthStatusEnum getByCode(String code) {
- for (HealthStatusEnum e : HealthStatusEnum.values()) {
- if (e.code.equals(code)) {
- return e;
- }
- }
- return null;
- }
-
- public static String getDescByCode(String code) {
- HealthStatusEnum e = getByCode(code);
- return null == e ? null : e.desc;
- }
-
- public static List listAll() {
- List list = new ArrayList<>(HealthStatusEnum.values().length);
- for (HealthStatusEnum e : HealthStatusEnum.values()) {
- JSONObject jsonObject = new JSONObject();
- jsonObject.set(e.code, e.desc);
- list.add(jsonObject);
- }
- return list;
- }
+package com.dite.znpt.enums;
+
+import cn.hutool.json.JSONObject;
+import lombok.Getter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Bear.G
+ * @date 2025/7/31/周四 15:30
+ * @description 设备健康状态枚举
+ */
+@Getter
+public enum HealthStatusEnum {
+ EXCELLENT("excellent", "优秀"),
+ GOOD("good", "良好"),
+ NORMAL("normal", "一般"),
+ POOR("poor", "较差"),
+ BAD("bad", "差");
+
+ private final String code;
+ private final String desc;
+
+ HealthStatusEnum(String code, String desc) {
+ this.code = code;
+ this.desc = desc;
+ }
+
+ public static HealthStatusEnum getByCode(String code) {
+ for (HealthStatusEnum e : HealthStatusEnum.values()) {
+ if (e.code.equals(code)) {
+ return e;
+ }
+ }
+ return null;
+ }
+
+ public static String getDescByCode(String code) {
+ HealthStatusEnum e = getByCode(code);
+ return null == e ? null : e.desc;
+ }
+
+ public static List listAll() {
+ List list = new ArrayList<>(HealthStatusEnum.values().length);
+ for (HealthStatusEnum e : HealthStatusEnum.values()) {
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.set(e.code, e.desc);
+ list.add(jsonObject);
+ }
+ return list;
+ }
}
\ No newline at end of file
diff --git a/core/src/main/java/com/dite/znpt/enums/LocationStatusEnum.java b/core/src/main/java/com/dite/znpt/enums/LocationStatusEnum.java
index 8f95140..9e04826 100644
--- a/core/src/main/java/com/dite/znpt/enums/LocationStatusEnum.java
+++ b/core/src/main/java/com/dite/znpt/enums/LocationStatusEnum.java
@@ -1,55 +1,55 @@
-package com.dite.znpt.enums;
-
-import cn.hutool.json.JSONObject;
-import lombok.Getter;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author Bear.G
- * @date 2025/7/31/周四 15:30
- * @description 设备位置状态枚举
- */
-@Getter
-public enum LocationStatusEnum {
- IN_STOCK("in_stock", "库存中"),
- ALLOCATED("allocated", "已分配"),
- REPAIR("repair", "维修中"),
- SCRAP("scrap", "待报废"),
- SCRAPPED("scrapped", "已报废"),
- BORROWED("borrowed", "外借中"),
- LOST("lost", "丢失");
-
- private final String code;
- private final String desc;
-
- LocationStatusEnum(String code, String desc) {
- this.code = code;
- this.desc = desc;
- }
-
- public static LocationStatusEnum getByCode(String code) {
- for (LocationStatusEnum e : LocationStatusEnum.values()) {
- if (e.code.equals(code)) {
- return e;
- }
- }
- return null;
- }
-
- public static String getDescByCode(String code) {
- LocationStatusEnum e = getByCode(code);
- return null == e ? null : e.desc;
- }
-
- public static List listAll() {
- List list = new ArrayList<>(LocationStatusEnum.values().length);
- for (LocationStatusEnum e : LocationStatusEnum.values()) {
- JSONObject jsonObject = new JSONObject();
- jsonObject.set(e.code, e.desc);
- list.add(jsonObject);
- }
- return list;
- }
+package com.dite.znpt.enums;
+
+import cn.hutool.json.JSONObject;
+import lombok.Getter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Bear.G
+ * @date 2025/7/31/周四 15:30
+ * @description 设备位置状态枚举
+ */
+@Getter
+public enum LocationStatusEnum {
+ IN_STOCK("in_stock", "库存中"),
+ ALLOCATED("allocated", "已分配"),
+ REPAIR("repair", "维修中"),
+ SCRAP("scrap", "待报废"),
+ SCRAPPED("scrapped", "已报废"),
+ BORROWED("borrowed", "外借中"),
+ LOST("lost", "丢失");
+
+ private final String code;
+ private final String desc;
+
+ LocationStatusEnum(String code, String desc) {
+ this.code = code;
+ this.desc = desc;
+ }
+
+ public static LocationStatusEnum getByCode(String code) {
+ for (LocationStatusEnum e : LocationStatusEnum.values()) {
+ if (e.code.equals(code)) {
+ return e;
+ }
+ }
+ return null;
+ }
+
+ public static String getDescByCode(String code) {
+ LocationStatusEnum e = getByCode(code);
+ return null == e ? null : e.desc;
+ }
+
+ public static List listAll() {
+ List list = new ArrayList<>(LocationStatusEnum.values().length);
+ for (LocationStatusEnum e : LocationStatusEnum.values()) {
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.set(e.code, e.desc);
+ list.add(jsonObject);
+ }
+ return list;
+ }
}
\ No newline at end of file
diff --git a/core/src/main/java/com/dite/znpt/mapper/BusinessDataFileMapper.java b/core/src/main/java/com/dite/znpt/mapper/BusinessDataFileMapper.java
index 0420931..6192769 100644
--- a/core/src/main/java/com/dite/znpt/mapper/BusinessDataFileMapper.java
+++ b/core/src/main/java/com/dite/znpt/mapper/BusinessDataFileMapper.java
@@ -1,23 +1,20 @@
-package com.dite.znpt.mapper;
-
-import com.dite.znpt.domain.entity.BusinessDataFileEntity;
-import com.dite.znpt.domain.entity.BusinessDataEntity;
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiOperation;
-import org.apache.ibatis.annotations.Param;
-import org.apache.ibatis.annotations.Select;
-
-import java.util.List;
-
-@ApiOperation("商务资料文件对象")
-public interface BusinessDataFileMapper {
- public List List(@Param("folderId") Long folderId, @Param("fileName") String fileName);
- void delete(@Param("fileId") Long fileId,@Param("folderId") Long folderId);
-
- void add(BusinessDataFileEntity businessDataFileEntity);
-
- String getPath(Long fileId);
-
- // 在接口中添加重命名方法
- void reName(@Param("fileId") Long fileId, @Param("newFileName") String newFileName, @Param("newFilePath") String newFilePath);
-}
+package com.dite.znpt.mapper;
+
+import com.dite.znpt.domain.entity.BusinessDataFileEntity;
+import io.swagger.annotations.ApiOperation;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+@ApiOperation("商务资料文件对象")
+public interface BusinessDataFileMapper {
+ public List List(@Param("folderId") Long folderId, @Param("fileName") String fileName);
+ void delete(@Param("fileId") Long fileId,@Param("folderId") Long folderId);
+
+ void add(BusinessDataFileEntity businessDataFileEntity);
+
+ String getPath(Long fileId);
+
+ // 在接口中添加重命名方法
+ void reName(@Param("fileId") Long fileId, @Param("newFileName") String newFileName, @Param("newFilePath") String newFilePath);
+}
diff --git a/core/src/main/java/com/dite/znpt/mapper/BusinessDataMapper.java b/core/src/main/java/com/dite/znpt/mapper/BusinessDataMapper.java
index 9d1d686..b92887f 100644
--- a/core/src/main/java/com/dite/znpt/mapper/BusinessDataMapper.java
+++ b/core/src/main/java/com/dite/znpt/mapper/BusinessDataMapper.java
@@ -1,31 +1,26 @@
-package com.dite.znpt.mapper;
-
-import com.baomidou.mybatisplus.core.injector.methods.SelectList;
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.dite.znpt.domain.entity.BusinessDataEntity;
-import io.swagger.annotations.ApiOperation;
-import org.apache.ibatis.annotations.Param;
-import org.apache.ibatis.annotations.Select;
-import com.dite.znpt.domain.entity.BusinessDataEntity;
-
-import java.time.LocalDateTime;
-import java.util.List;
-
-
-
-
-
-@ApiOperation("商务资料文件夹对象")
-public interface BusinessDataMapper {
- public String getPath(Long parentId);
-
- public List List();
-
- void insert(BusinessDataEntity businessDataEntity);
-
- void delete(Long folderId);
-
- void reName(BusinessDataEntity businessDataEntity);
-
- public List ListWithCondition(@Param("folderName") String folderName);
-}
+package com.dite.znpt.mapper;
+
+import com.dite.znpt.domain.entity.BusinessDataEntity;
+import io.swagger.annotations.ApiOperation;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+
+
+
+
+@ApiOperation("商务资料文件夹对象")
+public interface BusinessDataMapper {
+ public String getPath(Long parentId);
+
+ public List List();
+
+ void insert(BusinessDataEntity businessDataEntity);
+
+ void delete(Long folderId);
+
+ void reName(BusinessDataEntity businessDataEntity);
+
+ public List ListWithCondition(@Param("folderName") String folderName);
+}
diff --git a/core/src/main/java/com/dite/znpt/service/BusinessDataFileService.java b/core/src/main/java/com/dite/znpt/service/BusinessDataFileService.java
index 031a4c3..5b8d99c 100644
--- a/core/src/main/java/com/dite/znpt/service/BusinessDataFileService.java
+++ b/core/src/main/java/com/dite/znpt/service/BusinessDataFileService.java
@@ -1,29 +1,27 @@
-package com.dite.znpt.service;
-
-import com.dite.znpt.domain.Result;
-import com.dite.znpt.domain.entity.BusinessDataFileEntity;
-import com.dite.znpt.domain.page.PageBean;
-import io.swagger.annotations.ApiOperation;
-import org.springframework.stereotype.Service;
-import org.springframework.web.bind.annotation.RequestParam;
-
-import javax.servlet.http.HttpServletResponse;
-
-@ApiOperation("商务资料文件service")
-@Service
-public interface BusinessDataFileService {
-
- PageBean pageSelect(Integer page, Integer pageSize, Long folderId, String fileName);
-
- Result delete(@RequestParam(value = "fileId", required = false) Long fileId,@RequestParam(value = "foldelId", required = false) Long folderId);
-
- void add(BusinessDataFileEntity businessDataFileEntity);
-
- String getPath(Long fileId);
-
- // 在接口中添加重命名方法
- Result reName(Long fileId, String newFileName);
-
- // 在接口中添加预览方法
-// Result preview(Long fileId, HttpServletResponse response);
-}
+package com.dite.znpt.service;
+
+import com.dite.znpt.domain.Result;
+import com.dite.znpt.domain.entity.BusinessDataFileEntity;
+import com.dite.znpt.domain.page.PageBean;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.stereotype.Service;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@ApiOperation("商务资料文件service")
+@Service
+public interface BusinessDataFileService {
+
+ PageBean pageSelect(Integer page, Integer pageSize, Long folderId, String fileName);
+
+ Result delete(@RequestParam(value = "fileId", required = false) Long fileId,@RequestParam(value = "foldelId", required = false) Long folderId);
+
+ void add(BusinessDataFileEntity businessDataFileEntity);
+
+ String getPath(Long fileId);
+
+ // 在接口中添加重命名方法
+ Result reName(Long fileId, String newFileName);
+
+ // 在接口中添加预览方法
+// Result preview(Long fileId, HttpServletResponse response);
+}
diff --git a/core/src/main/java/com/dite/znpt/service/BusinessDataService.java b/core/src/main/java/com/dite/znpt/service/BusinessDataService.java
index 0aa585d..ec37987 100644
--- a/core/src/main/java/com/dite/znpt/service/BusinessDataService.java
+++ b/core/src/main/java/com/dite/znpt/service/BusinessDataService.java
@@ -1,15 +1,15 @@
-package com.dite.znpt.service;
-
-import com.dite.znpt.domain.Result;
-import com.dite.znpt.domain.page.PageBean;
-import io.swagger.annotations.ApiOperation;
-
-@ApiOperation("商务资料文件夹service")
-public interface BusinessDataService {
-
- PageBean pageSelect(Integer page, Integer pageSize, String folderName);
- Result createFolder(String folderName, Long parentId);
- String getPath(Long parentId);
- Result delete(Long folderId);
- Result reName(Long folderId, String newName);
-}
+package com.dite.znpt.service;
+
+import com.dite.znpt.domain.Result;
+import com.dite.znpt.domain.page.PageBean;
+import io.swagger.annotations.ApiOperation;
+
+@ApiOperation("商务资料文件夹service")
+public interface BusinessDataService {
+
+ PageBean pageSelect(Integer page, Integer pageSize, String folderName);
+ Result createFolder(String folderName, Long parentId);
+ String getPath(Long parentId);
+ Result delete(Long folderId);
+ Result reName(Long folderId, String newName);
+}
diff --git a/core/src/main/java/com/dite/znpt/service/EmailService.java b/core/src/main/java/com/dite/znpt/service/EmailService.java
index e13ba73..51a05f0 100644
--- a/core/src/main/java/com/dite/znpt/service/EmailService.java
+++ b/core/src/main/java/com/dite/znpt/service/EmailService.java
@@ -1,30 +1,30 @@
-package com.dite.znpt.service;
-
-import org.springframework.stereotype.Service;
-
-@Service
-public interface EmailService {
- /**
- * 发送邮箱验证码
- * @param email
- * @param code
- * @return
- */
- public boolean sendVerificationCode(String email, String code);
-
- /**
- * 生成验证码
- * @param email
- * @return
- */
- public String generateCode(String email);
-
- /**
- * 验证邮箱验证码
- * @param email
- * @param code
- * @return
- */
- public boolean verifyCode(String email, String code);
-
-}
+//package com.dite.znpt.service;
+//
+//import org.springframework.stereotype.Service;
+//
+//@Service
+//public interface EmailService {
+// /**
+// * 发送邮箱验证码
+// * @param email
+// * @param code
+// * @return
+// */
+// public boolean sendVerificationCode(String email, String code);
+//
+// /**
+// * 生成验证码
+// * @param email
+// * @return
+// */
+// public String generateCode(String email);
+//
+// /**
+// * 验证邮箱验证码
+// * @param email
+// * @param code
+// * @return
+// */
+// public boolean verifyCode(String email, String code);
+//
+//}
diff --git a/core/src/main/java/com/dite/znpt/service/ProjectBudgetInfoService.java b/core/src/main/java/com/dite/znpt/service/ProjectBudgetInfoService.java
index fa32837..dd8c56a 100644
--- a/core/src/main/java/com/dite/znpt/service/ProjectBudgetInfoService.java
+++ b/core/src/main/java/com/dite/znpt/service/ProjectBudgetInfoService.java
@@ -2,7 +2,10 @@ package com.dite.znpt.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.dite.znpt.domain.entity.ProjectBudgetInfoEntity;
-import com.dite.znpt.domain.vo.*;
+import com.dite.znpt.domain.vo.ProjectBudgetInfoDetailResp;
+import com.dite.znpt.domain.vo.ProjectBudgetInfoImportReq;
+import com.dite.znpt.domain.vo.ProjectBudgetInfoListReq;
+import com.dite.znpt.domain.vo.ProjectBudgetInfoListResp;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
diff --git a/core/src/main/java/com/dite/znpt/service/UserPostService.java b/core/src/main/java/com/dite/znpt/service/UserPostService.java
index c2a86ab..1060aff 100644
--- a/core/src/main/java/com/dite/znpt/service/UserPostService.java
+++ b/core/src/main/java/com/dite/znpt/service/UserPostService.java
@@ -1,7 +1,6 @@
package com.dite.znpt.service;
import com.baomidou.mybatisplus.extension.service.IService;
-import com.dite.znpt.domain.entity.PostEntity;
import com.dite.znpt.domain.entity.UserPostEntity;
import com.dite.znpt.domain.vo.PostResp;
import com.dite.znpt.domain.vo.UserResp;
diff --git a/core/src/main/java/com/dite/znpt/service/impl/BusinessDataFileServiceImpl.java b/core/src/main/java/com/dite/znpt/service/impl/BusinessDataFileServiceImpl.java
index c138abf..2392b49 100644
--- a/core/src/main/java/com/dite/znpt/service/impl/BusinessDataFileServiceImpl.java
+++ b/core/src/main/java/com/dite/znpt/service/impl/BusinessDataFileServiceImpl.java
@@ -1,163 +1,163 @@
-package com.dite.znpt.service.impl;
-
-
-
-import com.dite.znpt.domain.Result;
-import com.dite.znpt.domain.entity.BusinessDataFileEntity;
-import com.dite.znpt.domain.page.PageBean;
-import com.dite.znpt.mapper.BusinessDataFileMapper;
-import com.dite.znpt.service.BusinessDataFileService;
-import com.github.pagehelper.Page;
-import com.github.pagehelper.PageHelper;
-import io.swagger.annotations.ApiOperation;
-import lombok.AllArgsConstructor;
-import org.springframework.stereotype.Service;
-
-import javax.annotation.Resource;
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-
-import static jodd.io.FileUtil.deleteFile;
-import static org.apache.tomcat.util.http.fileupload.FileUtils.deleteDirectory;
-
-@AllArgsConstructor
-@Service
-@ApiOperation("商务资料文件service实现类")
-public class BusinessDataFileServiceImpl implements BusinessDataFileService {
- @Resource
- private BusinessDataFileMapper businessDataFileMapper;
-
-
- @ApiOperation("分页查询文件")
- @Override
- public PageBean pageSelect(Integer page, Integer pageSize, Long folderId, String fileName) {
- PageHelper.startPage(page, pageSize);
- List list = businessDataFileMapper.List(folderId, fileName);
- Page p = (Page) list;
- PageBean pageBean = new PageBean(p.getTotal(), p.getResult());
- return pageBean;
- }
- @ApiOperation("删除文件")
- public Result delete(Long fileId, Long folderId) {
- //删除数据库数据
- if (folderId != null){
- businessDataFileMapper.delete(null,folderId);
- System.out.println("888888888走对了");
-
- return Result.okM("删除,走对了,成功");
- }
-
- //删除文件
- String sPath = businessDataFileMapper.getPath(fileId);
-
- businessDataFileMapper.delete(fileId,null);
-
- boolean flag = false;
- File file = new File(sPath);
- // 判断目录或文件是否存在
- if (!file.exists()) { // 不存在返回 false
- return Result.error("文件不存在");
- } else {
- // 判断是否为文件
- if (file.isFile()) { // 为文件时调用删除文件方法
- try {
- deleteFile(file);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- return Result.okM("删除成功");
- } else { // 为目录时调用删除目录方法
- try {
- deleteDirectory(file);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- return Result.okM("删除成功");
- }
- }
-
-
- }
-
- @ApiOperation("增加文件")
- public void add(BusinessDataFileEntity businessDataFileEntity) {
- businessDataFileMapper.add(businessDataFileEntity);
- }
-
- @ApiOperation("获取文件路径")
- public String getPath(Long fileId) {
- return businessDataFileMapper.getPath(fileId);
- }
-
- @ApiOperation("重命名文件")
- @Override
- public Result reName(Long fileId, String newFileName) {
- // 参数校验
- if (fileId == null) {
- return Result.error("文件ID不能为空");
- }
- if (newFileName == null || newFileName.trim().isEmpty()) {
- return Result.error("新文件名不能为空");
- }
- if (newFileName.length() > 100) {
- return Result.error("文件名过长");
- }
-
- try {
- // 获取原文件信息
- String oldFilePath = businessDataFileMapper.getPath(fileId);
- if (oldFilePath == null) {
- return Result.error("文件不存在");
- }
-
- // 创建原文件对象
- File oldFile = new File(oldFilePath);
- if (!oldFile.exists()) {
- return Result.error("文件不存在");
- }
-
- // 构建新文件路径
- String parentPath = oldFile.getParent();
- String fileExtension = "";
- String fileNameWithoutExt = newFileName;
-
- // 获取原文件扩展名
- int lastDotIndex = oldFile.getName().lastIndexOf('.');
- if (lastDotIndex > 0) {
- fileExtension = oldFile.getName().substring(lastDotIndex);
- }
-
- // 如果新文件名没有扩展名,则添加原文件扩展名
- if (!newFileName.contains(".")) {
- newFileName = newFileName + fileExtension;
- }
-
- // 构建新文件路径
- String newFilePath = parentPath + File.separator + newFileName;
- File newFile = new File(newFilePath);
-
- // 检查新文件名是否已存在
- if (newFile.exists()) {
- return Result.error("文件名已存在");
- }
-
- // 重命名实际文件
- boolean renameSuccess = oldFile.renameTo(newFile);
- if (!renameSuccess) {
- return Result.error("文件重命名失败");
- }
-
- // 更新数据库中的文件信息
- businessDataFileMapper.reName(fileId, newFileName, newFilePath);
-
- return Result.okM("文件重命名成功");
-
- } catch (Exception e) {
- return Result.error("文件重命名失败: " + e.getMessage());
- }
- }
-
-
-
-}
+package com.dite.znpt.service.impl;
+
+
+
+import com.dite.znpt.domain.Result;
+import com.dite.znpt.domain.entity.BusinessDataFileEntity;
+import com.dite.znpt.domain.page.PageBean;
+import com.dite.znpt.mapper.BusinessDataFileMapper;
+import com.dite.znpt.service.BusinessDataFileService;
+import com.github.pagehelper.Page;
+import com.github.pagehelper.PageHelper;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import static jodd.io.FileUtil.deleteFile;
+import static org.apache.tomcat.util.http.fileupload.FileUtils.deleteDirectory;
+
+@AllArgsConstructor
+@Service
+@ApiOperation("商务资料文件service实现类")
+public class BusinessDataFileServiceImpl implements BusinessDataFileService {
+ @Resource
+ private BusinessDataFileMapper businessDataFileMapper;
+
+
+ @ApiOperation("分页查询文件")
+ @Override
+ public PageBean pageSelect(Integer page, Integer pageSize, Long folderId, String fileName) {
+ PageHelper.startPage(page, pageSize);
+ List list = businessDataFileMapper.List(folderId, fileName);
+ Page p = (Page) list;
+ PageBean pageBean = new PageBean(p.getTotal(), p.getResult());
+ return pageBean;
+ }
+ @ApiOperation("删除文件")
+ public Result delete(Long fileId, Long folderId) {
+ //删除数据库数据
+ if (folderId != null){
+ businessDataFileMapper.delete(null,folderId);
+ System.out.println("888888888走对了");
+
+ return Result.okM("删除,走对了,成功");
+ }
+
+ //删除文件
+ String sPath = businessDataFileMapper.getPath(fileId);
+
+ businessDataFileMapper.delete(fileId,null);
+
+ boolean flag = false;
+ File file = new File(sPath);
+ // 判断目录或文件是否存在
+ if (!file.exists()) { // 不存在返回 false
+ return Result.error("文件不存在");
+ } else {
+ // 判断是否为文件
+ if (file.isFile()) { // 为文件时调用删除文件方法
+ try {
+ deleteFile(file);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ return Result.okM("删除成功");
+ } else { // 为目录时调用删除目录方法
+ try {
+ deleteDirectory(file);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ return Result.okM("删除成功");
+ }
+ }
+
+
+ }
+
+ @ApiOperation("增加文件")
+ public void add(BusinessDataFileEntity businessDataFileEntity) {
+ businessDataFileMapper.add(businessDataFileEntity);
+ }
+
+ @ApiOperation("获取文件路径")
+ public String getPath(Long fileId) {
+ return businessDataFileMapper.getPath(fileId);
+ }
+
+ @ApiOperation("重命名文件")
+ @Override
+ public Result reName(Long fileId, String newFileName) {
+ // 参数校验
+ if (fileId == null) {
+ return Result.error("文件ID不能为空");
+ }
+ if (newFileName == null || newFileName.trim().isEmpty()) {
+ return Result.error("新文件名不能为空");
+ }
+ if (newFileName.length() > 100) {
+ return Result.error("文件名过长");
+ }
+
+ try {
+ // 获取原文件信息
+ String oldFilePath = businessDataFileMapper.getPath(fileId);
+ if (oldFilePath == null) {
+ return Result.error("文件不存在");
+ }
+
+ // 创建原文件对象
+ File oldFile = new File(oldFilePath);
+ if (!oldFile.exists()) {
+ return Result.error("文件不存在");
+ }
+
+ // 构建新文件路径
+ String parentPath = oldFile.getParent();
+ String fileExtension = "";
+ String fileNameWithoutExt = newFileName;
+
+ // 获取原文件扩展名
+ int lastDotIndex = oldFile.getName().lastIndexOf('.');
+ if (lastDotIndex > 0) {
+ fileExtension = oldFile.getName().substring(lastDotIndex);
+ }
+
+ // 如果新文件名没有扩展名,则添加原文件扩展名
+ if (!newFileName.contains(".")) {
+ newFileName = newFileName + fileExtension;
+ }
+
+ // 构建新文件路径
+ String newFilePath = parentPath + File.separator + newFileName;
+ File newFile = new File(newFilePath);
+
+ // 检查新文件名是否已存在
+ if (newFile.exists()) {
+ return Result.error("文件名已存在");
+ }
+
+ // 重命名实际文件
+ boolean renameSuccess = oldFile.renameTo(newFile);
+ if (!renameSuccess) {
+ return Result.error("文件重命名失败");
+ }
+
+ // 更新数据库中的文件信息
+ businessDataFileMapper.reName(fileId, newFileName, newFilePath);
+
+ return Result.okM("文件重命名成功");
+
+ } catch (Exception e) {
+ return Result.error("文件重命名失败: " + e.getMessage());
+ }
+ }
+
+
+
+}
diff --git a/core/src/main/java/com/dite/znpt/service/impl/BusinessDataServiceImpl.java b/core/src/main/java/com/dite/znpt/service/impl/BusinessDataServiceImpl.java
index e5b60ce..3d74793 100644
--- a/core/src/main/java/com/dite/znpt/service/impl/BusinessDataServiceImpl.java
+++ b/core/src/main/java/com/dite/znpt/service/impl/BusinessDataServiceImpl.java
@@ -1,197 +1,197 @@
-package com.dite.znpt.service.impl;
-
-import com.dite.znpt.domain.Result;
-import com.dite.znpt.domain.entity.BusinessDataEntity;
-import com.dite.znpt.domain.page.PageBean;
-import com.dite.znpt.mapper.BusinessDataMapper;
-import com.dite.znpt.service.BusinessDataFileService;
-import com.dite.znpt.service.BusinessDataService;
-import com.github.pagehelper.Page;
-import com.github.pagehelper.PageHelper;
-import io.swagger.annotations.ApiOperation;
-import lombok.AllArgsConstructor;
-import lombok.NoArgsConstructor;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Service;
-
-import javax.annotation.Resource;
-import java.io.File;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.time.LocalDateTime;
-import java.util.Comparator;
-import java.util.List;
-
-/**
- * 商务资料文件夹实现类
- */
-@Service
-@ApiOperation("商务资料文件夹service实现类")
-@AllArgsConstructor
-@NoArgsConstructor
-public class BusinessDataServiceImpl implements BusinessDataService {
- @Resource
- private BusinessDataMapper businessDataMapper;
- @Resource
- private BusinessDataFileService businessDataFileService;
-
- // 从配置文件中读取基础路径(默认值:D:/upload/businessData)
- // ,新建文件夹的时候,如果没指定父文件夹Id,就用这个
- @Value("${file.upload.businessDataPath:D:/upload/businessData}")
- private String businessDataPath;
-
- @ApiOperation(value = "分页查询")
- @Override
- public PageBean pageSelect(Integer page, Integer pageSize, String folderName) {
- PageHelper.startPage(page, pageSize);
- List businessDataEntityList = businessDataMapper.ListWithCondition(folderName);
- Page p = (Page) businessDataEntityList;
- PageBean pageBean = new PageBean(p.getTotal(), p.getResult());
- return pageBean;
- }
-
- @ApiOperation(value = "创建文件夹")
- @Override
- public Result createFolder(String folderName, Long parentId) {
- //获取ID
- Long loginIdAsLong = 888L;
-// loginIdAsLong = StpUtil.getLoginIdAsLong();
-//
- // 文件夹名称不能为空
- //TODO: 添加文件夹名称校验,后续最好更规范些,写个工具类专门校验,用正则表达式
- if (folderName == null || folderName.trim().isEmpty()) {
- return Result.error("文件夹名称不能为空");
- }
- if (folderName.length() > 50) {
- return Result.error("文件夹名称过长");
- }
-
- // 文件夹名称前置一个/
- String folderName1 = "/" + folderName;
- // 目标文件夹
- File targetDir=Paths.get(businessDataPath, folderName1).toFile();
- if(parentId != 0L){
- // 获取父文件夹路径
- targetDir = Paths.get(businessDataMapper.getPath(parentId), folderName1).toFile();
- }
- // 创建文件夹和新增文件夹路径
- if (!targetDir.exists()) {
- // 创建文件夹
- boolean created = targetDir.mkdirs();
- if (!created) {
- throw new RuntimeException("文件夹创建失败: " + targetDir.getAbsolutePath());
- }
- //上面是新增文件夹功能,但没有往数据库插入文件夹相关数据,所以下面新增
- // 创建BusinessDataEntity对象并设置属性
- BusinessDataEntity businessDataEntity = new BusinessDataEntity(
- null,
- folderName,
- parentId,
- loginIdAsLong,
- LocalDateTime.now(),
- LocalDateTime.now(),
- false,
- targetDir.getAbsolutePath()
- );
- // 插入到数据库
- businessDataMapper.insert(businessDataEntity);
- return Result.okM( "文件夹创建成功");
- } else {
- return Result.error("文件夹已存在: ");
- }
- }
-
- @ApiOperation("获取文件夹路径")
- public String getPath(Long parentId) {
- return businessDataMapper.getPath(parentId);
- }
-
-// @ApiOperation("删除文件夹")
-// @Override
-// public Result delete(Long folderId) {
-// // 获取文件夹路径
-// String folderPath = businessDataMapper.getPath(folderId);
-//
-// // 创建File对象并删除文件夹
-// File folder = new File(folderPath);
-// if (folder.exists()) {
-// boolean deleted = folder.delete();
-// if (!deleted) {
-// // throw new RuntimeException("文件夹删除失败: " + folderPath);
-// // TODO: 以后可以用全局异常处理器捕获,或者用try catch捕获
-// return Result.error("文件夹删除失败: " + folderPath);
-// }
-// //删除数据库中文件夹的数据
-// businessDataMapper.delete(folderId);
-// //删除文件夹下文件的数据
-// businessDataFileService.delete(folderId);
-// return Result.okM("删除成功");
-// } else {
-// // throw new RuntimeException("文件夹不存在: " + folderPath);
-// return Result.error("文件夹不存在: " + folderPath);
-// }
-// }
- @ApiOperation("删除文件夹")
- @Override
- public Result delete(Long folderId) {
- // 获取文件夹路径
- String folderPath = businessDataMapper.getPath(folderId);
-
- // 创建Path对象并删除文件夹
- Path folder = Paths.get(folderPath);
- if (Files.exists(folder)) {
- try {
- // 使用Files.walk获取所有文件和目录,按深度排序后删除
- java.util.stream.Stream filePaths = Files.walk(folder);
- filePaths.sorted(Comparator.reverseOrder())
- .map(Path::toFile)
- .forEach(File::delete);
- filePaths.close();
-
- //删除数据库中文件夹的数据
- businessDataMapper.delete(folderId);
- //删除文件夹下文件的数据
- businessDataFileService.delete(null , folderId);
- return Result.okM("删除成功");
- } catch (Exception e) {
- return Result.okM("删除成功");
- }
- } else {
- return Result.error("文件夹不存在: " + folderPath);
- }
- }
- @ApiOperation("重命名文件夹")
- @Override
- public Result reName(Long folderId, String newName) {
- // 获取文件夹路径
- String folderPath = businessDataMapper.getPath(folderId);
- String newPath = folderPath.substring(0, folderPath.lastIndexOf('\\'))+"\\" + newName;
- System.out.printf("7777777"+newPath);
-//
-// //想命名的原文件的路径
-// File file = new File("f:/a/a.xlsx");
-// //将原文件更改为f:\a\b.xlsx,其中路径是必要的。注意
-// file.renameTo(new File("f:/a/b.xlsx"));
- //想命名的原文件夹的路径
- File file1 = new File(folderPath);
- //将原文件夹更改为A,其中路径是必要的。注意
- file1.renameTo(new File(newPath));
- LocalDateTime now = LocalDateTime.now();
-
- BusinessDataEntity businessDataEntity = new BusinessDataEntity(
- folderId,
- newName,
- null,
- null,
- null,
- now,
- null,
- newPath
- );
- System.out.println(businessDataEntity);
- businessDataMapper.reName(businessDataEntity);
- return Result.okM("重命名成功");
- }
-
-}
+package com.dite.znpt.service.impl;
+
+import com.dite.znpt.domain.Result;
+import com.dite.znpt.domain.entity.BusinessDataEntity;
+import com.dite.znpt.domain.page.PageBean;
+import com.dite.znpt.mapper.BusinessDataMapper;
+import com.dite.znpt.service.BusinessDataFileService;
+import com.dite.znpt.service.BusinessDataService;
+import com.github.pagehelper.Page;
+import com.github.pagehelper.PageHelper;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import lombok.NoArgsConstructor;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.time.LocalDateTime;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * 商务资料文件夹实现类
+ */
+@Service
+@ApiOperation("商务资料文件夹service实现类")
+@AllArgsConstructor
+@NoArgsConstructor
+public class BusinessDataServiceImpl implements BusinessDataService {
+ @Resource
+ private BusinessDataMapper businessDataMapper;
+ @Resource
+ private BusinessDataFileService businessDataFileService;
+
+ // 从配置文件中读取基础路径(默认值:D:/upload/businessData)
+ // ,新建文件夹的时候,如果没指定父文件夹Id,就用这个
+ @Value("${file.upload.businessDataPath:D:/upload/businessData}")
+ private String businessDataPath;
+
+ @ApiOperation(value = "分页查询")
+ @Override
+ public PageBean pageSelect(Integer page, Integer pageSize, String folderName) {
+ PageHelper.startPage(page, pageSize);
+ List businessDataEntityList = businessDataMapper.ListWithCondition(folderName);
+ Page p = (Page) businessDataEntityList;
+ PageBean pageBean = new PageBean(p.getTotal(), p.getResult());
+ return pageBean;
+ }
+
+ @ApiOperation(value = "创建文件夹")
+ @Override
+ public Result createFolder(String folderName, Long parentId) {
+ //获取ID
+ Long loginIdAsLong = 888L;
+// loginIdAsLong = StpUtil.getLoginIdAsLong();
+//
+ // 文件夹名称不能为空
+ //TODO: 添加文件夹名称校验,后续最好更规范些,写个工具类专门校验,用正则表达式
+ if (folderName == null || folderName.trim().isEmpty()) {
+ return Result.error("文件夹名称不能为空");
+ }
+ if (folderName.length() > 50) {
+ return Result.error("文件夹名称过长");
+ }
+
+ // 文件夹名称前置一个/
+ String folderName1 = "/" + folderName;
+ // 目标文件夹
+ File targetDir=Paths.get(businessDataPath, folderName1).toFile();
+ if(parentId != 0L){
+ // 获取父文件夹路径
+ targetDir = Paths.get(businessDataMapper.getPath(parentId), folderName1).toFile();
+ }
+ // 创建文件夹和新增文件夹路径
+ if (!targetDir.exists()) {
+ // 创建文件夹
+ boolean created = targetDir.mkdirs();
+ if (!created) {
+ throw new RuntimeException("文件夹创建失败: " + targetDir.getAbsolutePath());
+ }
+ //上面是新增文件夹功能,但没有往数据库插入文件夹相关数据,所以下面新增
+ // 创建BusinessDataEntity对象并设置属性
+ BusinessDataEntity businessDataEntity = new BusinessDataEntity(
+ null,
+ folderName,
+ parentId,
+ loginIdAsLong,
+ LocalDateTime.now(),
+ LocalDateTime.now(),
+ false,
+ targetDir.getAbsolutePath()
+ );
+ // 插入到数据库
+ businessDataMapper.insert(businessDataEntity);
+ return Result.okM( "文件夹创建成功");
+ } else {
+ return Result.error("文件夹已存在: ");
+ }
+ }
+
+ @ApiOperation("获取文件夹路径")
+ public String getPath(Long parentId) {
+ return businessDataMapper.getPath(parentId);
+ }
+
+// @ApiOperation("删除文件夹")
+// @Override
+// public Result delete(Long folderId) {
+// // 获取文件夹路径
+// String folderPath = businessDataMapper.getPath(folderId);
+//
+// // 创建File对象并删除文件夹
+// File folder = new File(folderPath);
+// if (folder.exists()) {
+// boolean deleted = folder.delete();
+// if (!deleted) {
+// // throw new RuntimeException("文件夹删除失败: " + folderPath);
+// // TODO: 以后可以用全局异常处理器捕获,或者用try catch捕获
+// return Result.error("文件夹删除失败: " + folderPath);
+// }
+// //删除数据库中文件夹的数据
+// businessDataMapper.delete(folderId);
+// //删除文件夹下文件的数据
+// businessDataFileService.delete(folderId);
+// return Result.okM("删除成功");
+// } else {
+// // throw new RuntimeException("文件夹不存在: " + folderPath);
+// return Result.error("文件夹不存在: " + folderPath);
+// }
+// }
+ @ApiOperation("删除文件夹")
+ @Override
+ public Result delete(Long folderId) {
+ // 获取文件夹路径
+ String folderPath = businessDataMapper.getPath(folderId);
+
+ // 创建Path对象并删除文件夹
+ Path folder = Paths.get(folderPath);
+ if (Files.exists(folder)) {
+ try {
+ // 使用Files.walk获取所有文件和目录,按深度排序后删除
+ java.util.stream.Stream filePaths = Files.walk(folder);
+ filePaths.sorted(Comparator.reverseOrder())
+ .map(Path::toFile)
+ .forEach(File::delete);
+ filePaths.close();
+
+ //删除数据库中文件夹的数据
+ businessDataMapper.delete(folderId);
+ //删除文件夹下文件的数据
+ businessDataFileService.delete(null , folderId);
+ return Result.okM("删除成功");
+ } catch (Exception e) {
+ return Result.okM("删除成功");
+ }
+ } else {
+ return Result.error("文件夹不存在: " + folderPath);
+ }
+ }
+ @ApiOperation("重命名文件夹")
+ @Override
+ public Result reName(Long folderId, String newName) {
+ // 获取文件夹路径
+ String folderPath = businessDataMapper.getPath(folderId);
+ String newPath = folderPath.substring(0, folderPath.lastIndexOf('\\'))+"\\" + newName;
+ System.out.printf("7777777"+newPath);
+//
+// //想命名的原文件的路径
+// File file = new File("f:/a/a.xlsx");
+// //将原文件更改为f:\a\b.xlsx,其中路径是必要的。注意
+// file.renameTo(new File("f:/a/b.xlsx"));
+ //想命名的原文件夹的路径
+ File file1 = new File(folderPath);
+ //将原文件夹更改为A,其中路径是必要的。注意
+ file1.renameTo(new File(newPath));
+ LocalDateTime now = LocalDateTime.now();
+
+ BusinessDataEntity businessDataEntity = new BusinessDataEntity(
+ folderId,
+ newName,
+ null,
+ null,
+ null,
+ now,
+ null,
+ newPath
+ );
+ System.out.println(businessDataEntity);
+ businessDataMapper.reName(businessDataEntity);
+ return Result.okM("重命名成功");
+ }
+
+}
diff --git a/core/src/main/java/com/dite/znpt/service/impl/ContractServiceImpl.java b/core/src/main/java/com/dite/znpt/service/impl/ContractServiceImpl.java
index 2f830c9..8794210 100644
--- a/core/src/main/java/com/dite/znpt/service/impl/ContractServiceImpl.java
+++ b/core/src/main/java/com/dite/znpt/service/impl/ContractServiceImpl.java
@@ -1,17 +1,18 @@
package com.dite.znpt.service.impl;
import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dite.znpt.domain.entity.ContractEntity;
import com.dite.znpt.domain.vo.ContractListReq;
-import com.dite.znpt.domain.vo.ContractResp;
import com.dite.znpt.domain.vo.ContractReq;
-import com.dite.znpt.service.ContractService;
+import com.dite.znpt.domain.vo.ContractResp;
+import com.dite.znpt.enums.ContractStatusEnum;
import com.dite.znpt.mapper.ContractMapper;
-import org.springframework.stereotype.Service;
-import cn.hutool.core.collection.CollUtil;
-import lombok.RequiredArgsConstructor;
+import com.dite.znpt.service.ContractService;
import com.dite.znpt.util.PageUtil;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
import java.util.List;
@@ -37,7 +38,7 @@ public class ContractServiceImpl extends ServiceImpl contractList= this.baseMapper.queryBySelective(contractReq);
contractList.forEach(resp -> {
-
+ resp.setContractStatusLabel(ContractStatusEnum.getDescByCode(resp.getContractStatus()));
});
return contractList;
}
diff --git a/core/src/main/java/com/dite/znpt/service/impl/EmailServiceImpl.java b/core/src/main/java/com/dite/znpt/service/impl/EmailServiceImpl.java
index ea93d8d..42c9ed7 100644
--- a/core/src/main/java/com/dite/znpt/service/impl/EmailServiceImpl.java
+++ b/core/src/main/java/com/dite/znpt/service/impl/EmailServiceImpl.java
@@ -1,66 +1,66 @@
-package com.dite.znpt.service.impl;
-
-import com.dite.znpt.service.EmailService;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.http.HttpStatus;
-import org.springframework.mail.SimpleMailMessage;
-import org.springframework.mail.javamail.JavaMailSender;
-import org.springframework.stereotype.Service;
-import org.springframework.web.server.ResponseStatusException;
-
-import java.util.Random;
-
-@Slf4j
-@Service
-public class EmailServiceImpl implements EmailService {
-
- @Autowired
- private JavaMailSender mailSender;
-
- @Autowired
- private InMemoryVerificationCodeStore codeStore;
-
- @Value("${email.verification.from}")
- private String from;
- @Value("${email.verification.subject}")
- private String subject;
- @Value("${email.verification.template}")
- private String template;
-
- @Override
- public boolean sendVerificationCode(String email, String code) {
- SimpleMailMessage message = new SimpleMailMessage();
- message.setFrom(from);
- message.setSubject(subject);
- message.setTo(email);
- message.setText(String.format(template,code));
- try{
- mailSender.send(message);
- return true;
- }catch (Exception e){
- log.error("发送邮件失败:",e);
- return false;
- }
- }
-
- @Override
- public String generateCode(String email) {
- if (!codeStore.canSend(email)) {
- throw new ResponseStatusException(
- HttpStatus.TOO_MANY_REQUESTS, // 429 状态码
- "验证码发送过于频繁,请稍后再试"
- );
- }
-
- String code = String.format("%04d", new Random().nextInt(9999));
- codeStore.save(email, code);
- return code;
- }
-
- @Override
- public boolean verifyCode(String email, String code) {
- return codeStore.validate(email, code);
- }
-}
+//package com.dite.znpt.service.impl;
+//
+//import com.dite.znpt.service.EmailService;
+//import lombok.extern.slf4j.Slf4j;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.beans.factory.annotation.Value;
+//import org.springframework.http.HttpStatus;
+//import org.springframework.mail.SimpleMailMessage;
+//import org.springframework.mail.javamail.JavaMailSender;
+//import org.springframework.stereotype.Service;
+//import org.springframework.web.server.ResponseStatusException;
+//
+//import java.util.Random;
+//
+//@Slf4j
+//@Service
+//public class EmailServiceImpl implements EmailService {
+//
+// @Autowired
+// private JavaMailSender mailSender;
+//
+// @Autowired
+// private InMemoryVerificationCodeStore codeStore;
+//
+// @Value("${email.verification.from}")
+// private String from;
+// @Value("${email.verification.subject}")
+// private String subject;
+// @Value("${email.verification.template}")
+// private String template;
+//
+// @Override
+// public boolean sendVerificationCode(String email, String code) {
+// SimpleMailMessage message = new SimpleMailMessage();
+// message.setFrom(from);
+// message.setSubject(subject);
+// message.setTo(email);
+// message.setText(String.format(template,code));
+// try{
+// mailSender.send(message);
+// return true;
+// }catch (Exception e){
+// log.error("发送邮件失败:",e);
+// return false;
+// }
+// }
+//
+// @Override
+// public String generateCode(String email) {
+// if (!codeStore.canSend(email)) {
+// throw new ResponseStatusException(
+// HttpStatus.TOO_MANY_REQUESTS, // 429 状态码
+// "验证码发送过于频繁,请稍后再试"
+// );
+// }
+//
+// String code = String.format("%04d", new Random().nextInt(9999));
+// codeStore.save(email, code);
+// return code;
+// }
+//
+// @Override
+// public boolean verifyCode(String email, String code) {
+// return codeStore.validate(email, code);
+// }
+//}
diff --git a/core/src/main/java/com/dite/znpt/service/impl/EquipmentServiceImpl.java b/core/src/main/java/com/dite/znpt/service/impl/EquipmentServiceImpl.java
index cb81ad6..8f15c6e 100644
--- a/core/src/main/java/com/dite/znpt/service/impl/EquipmentServiceImpl.java
+++ b/core/src/main/java/com/dite/znpt/service/impl/EquipmentServiceImpl.java
@@ -5,7 +5,6 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dite.znpt.constant.Message;
-// 移除EquipmentConverts导入,使用手动转换
import com.dite.znpt.domain.entity.EquipmentEntity;
import com.dite.znpt.domain.vo.EquipmentListReq;
import com.dite.znpt.domain.vo.EquipmentReq;
@@ -25,8 +24,6 @@ import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
-import java.util.Map;
-import java.util.HashMap;
/**
* @author Bear.G
diff --git a/core/src/main/java/com/dite/znpt/service/impl/InMemoryVerificationCodeStore.java b/core/src/main/java/com/dite/znpt/service/impl/InMemoryVerificationCodeStore.java
index 5b909b3..fb11b9c 100644
--- a/core/src/main/java/com/dite/znpt/service/impl/InMemoryVerificationCodeStore.java
+++ b/core/src/main/java/com/dite/znpt/service/impl/InMemoryVerificationCodeStore.java
@@ -1,74 +1,74 @@
-package com.dite.znpt.service.impl;
-
-import lombok.Data;
-import org.springframework.stereotype.Component;
-
-import java.time.LocalDateTime;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-@Component
-public class InMemoryVerificationCodeStore {
-
- // 存储邮箱验证码的map
- private final Map emailCodeMap = new ConcurrentHashMap<>();
-
- public void save(String email, String code){
- // 设置五分钟过期
- emailCodeMap.put(email,new codeInfo(code, LocalDateTime.now().plusMinutes(5)));
- }
-
- /**
- * 验证验证码
- * @param email
- * @param code
- * @return
- */
- public boolean validate(String email, String code){
- codeInfo codeInfo = emailCodeMap.get(email);
- if(codeInfo == null){
- return false;
- }
-
- boolean isValid = false;
- if(code.equals(codeInfo.getCode()) && LocalDateTime.now().isBefore(codeInfo.getExpireTime())){
- isValid = true;
- }
- if(isValid){
- emailCodeMap.remove(email);
- return true;
- }
- return false;
- }
-
- /**
- * 判断邮箱是否可发送验证码
- * @param email
- * @return
- */
- public boolean canSend(String email){
- codeInfo codeInfo = emailCodeMap.get(email);
- if(codeInfo != null && LocalDateTime.now().isBefore(codeInfo.getExpireTime())){
- return false;
- }
- return true;
- }
-
- @Data
- public static class codeInfo {
- // 验证码
- private String code;
-
- // 过期时间
- private LocalDateTime expireTime;
-
- // 上一次发送时间
- private LocalDateTime lastSendTime;
-
- public codeInfo(String code, LocalDateTime expireTime){
- this.code = code;
- this.expireTime = expireTime;
- this.lastSendTime = LocalDateTime.now();
- }
- }
-}
+package com.dite.znpt.service.impl;
+
+import lombok.Data;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDateTime;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Component
+public class InMemoryVerificationCodeStore {
+
+ // 存储邮箱验证码的map
+ private final Map emailCodeMap = new ConcurrentHashMap<>();
+
+ public void save(String email, String code){
+ // 设置五分钟过期
+ emailCodeMap.put(email,new codeInfo(code, LocalDateTime.now().plusMinutes(5)));
+ }
+
+ /**
+ * 验证验证码
+ * @param email
+ * @param code
+ * @return
+ */
+ public boolean validate(String email, String code){
+ codeInfo codeInfo = emailCodeMap.get(email);
+ if(codeInfo == null){
+ return false;
+ }
+
+ boolean isValid = false;
+ if(code.equals(codeInfo.getCode()) && LocalDateTime.now().isBefore(codeInfo.getExpireTime())){
+ isValid = true;
+ }
+ if(isValid){
+ emailCodeMap.remove(email);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * 判断邮箱是否可发送验证码
+ * @param email
+ * @return
+ */
+ public boolean canSend(String email){
+ codeInfo codeInfo = emailCodeMap.get(email);
+ if(codeInfo != null && LocalDateTime.now().isBefore(codeInfo.getExpireTime())){
+ return false;
+ }
+ return true;
+ }
+
+ @Data
+ public static class codeInfo {
+ // 验证码
+ private String code;
+
+ // 过期时间
+ private LocalDateTime expireTime;
+
+ // 上一次发送时间
+ private LocalDateTime lastSendTime;
+
+ public codeInfo(String code, LocalDateTime expireTime){
+ this.code = code;
+ this.expireTime = expireTime;
+ this.lastSendTime = LocalDateTime.now();
+ }
+ }
+}
diff --git a/core/src/main/java/com/dite/znpt/service/impl/ProjectBudgetInfoServiceImpl.java b/core/src/main/java/com/dite/znpt/service/impl/ProjectBudgetInfoServiceImpl.java
index c78c4a0..d6e847f 100644
--- a/core/src/main/java/com/dite/znpt/service/impl/ProjectBudgetInfoServiceImpl.java
+++ b/core/src/main/java/com/dite/znpt/service/impl/ProjectBudgetInfoServiceImpl.java
@@ -5,7 +5,10 @@ import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dite.znpt.domain.entity.ProjectBudgetInfoEntity;
import com.dite.znpt.domain.entity.ProjectEntity;
-import com.dite.znpt.domain.vo.*;
+import com.dite.znpt.domain.vo.ProjectBudgetInfoDetailResp;
+import com.dite.znpt.domain.vo.ProjectBudgetInfoImportReq;
+import com.dite.znpt.domain.vo.ProjectBudgetInfoListReq;
+import com.dite.znpt.domain.vo.ProjectBudgetInfoListResp;
import com.dite.znpt.mapper.ProjectBudgetInfoMapper;
import com.dite.znpt.service.ProjectBudgetInfoService;
import com.dite.znpt.service.ProjectService;
diff --git a/core/src/main/resources/mapper/BusinessDataFileMapper.xml b/core/src/main/resources/mapper/BusinessDataFileMapper.xml
index 2d3be14..3a129f4 100644
--- a/core/src/main/resources/mapper/BusinessDataFileMapper.xml
+++ b/core/src/main/resources/mapper/BusinessDataFileMapper.xml
@@ -1,50 +1,50 @@
-
-
-
-
-
- delete from business_data_part_file
-
-
- and file_id = #{fileId}
-
-
- and folder_id = #{folderId}
-
-
-
-
-
-
- insert into business_data_part_file (file_id, folder_id, file_name, file_path, file_type, file_size, upload_time, uploader_id, is_deleted)
- values (#{fileId}, #{folderId}, #{fileName}, #{filePath}, #{fileType}, #{fileSize}, #{uploadTime}, #{uploaderId}, #{isDeleted})
-
-
-
-
- update business_data_part_file
-
- file_name = #{newFileName},
- file_path = #{newFilePath},
-
- where file_id = #{fileId}
-
-
-
+
+
+
+
+
+ delete from business_data_part_file
+
+
+ and file_id = #{fileId}
+
+
+ and folder_id = #{folderId}
+
+
+
+
+
+
+ insert into business_data_part_file (file_id, folder_id, file_name, file_path, file_type, file_size, upload_time, uploader_id, is_deleted)
+ values (#{fileId}, #{folderId}, #{fileName}, #{filePath}, #{fileType}, #{fileSize}, #{uploadTime}, #{uploaderId}, #{isDeleted})
+
+
+
+
+ update business_data_part_file
+
+ file_name = #{newFileName},
+ file_path = #{newFilePath},
+
+ where file_id = #{fileId}
+
+
+
diff --git a/core/src/main/resources/mapper/BusinessDataMapper.xml b/core/src/main/resources/mapper/BusinessDataMapper.xml
index 9af3111..f714eae 100644
--- a/core/src/main/resources/mapper/BusinessDataMapper.xml
+++ b/core/src/main/resources/mapper/BusinessDataMapper.xml
@@ -1,55 +1,55 @@
-
-
-
-
- insert into business_data_part
-
- folder_name,
- parent_id,
- creator_id,
- create_time,
- update_time,
- is_deleted,
- folder_path,
-
-
- #{folderName},
- #{parentId},
- #{creatorId},
- #{createTime},
- #{updateTime},
- #{isDeleted},
- #{folderPath},
-
-
-
-
-
-
-
-
- delete from business_data_part where folder_id = #{folderId}
-
-
- update business_data_part
-
- folder_name = #{folderName},
- update_time = #{updateTime},
- folder_path = #{folderPath},
-
- where folder_id = #{folderId}
-
-
-
-
+
+
+
+
+ insert into business_data_part
+
+ folder_name,
+ parent_id,
+ creator_id,
+ create_time,
+ update_time,
+ is_deleted,
+ folder_path,
+
+
+ #{folderName},
+ #{parentId},
+ #{creatorId},
+ #{createTime},
+ #{updateTime},
+ #{isDeleted},
+ #{folderPath},
+
+
+
+
+
+
+
+
+ delete from business_data_part where folder_id = #{folderId}
+
+
+ update business_data_part
+
+ folder_name = #{folderName},
+ update_time = #{updateTime},
+ folder_path = #{folderPath},
+
+ where folder_id = #{folderId}
+
+
+
+
diff --git a/core/src/main/resources/mapper/ContractMapper.xml b/core/src/main/resources/mapper/ContractMapper.xml
index c2a698d..078d6e2 100644
--- a/core/src/main/resources/mapper/ContractMapper.xml
+++ b/core/src/main/resources/mapper/ContractMapper.xml
@@ -38,9 +38,6 @@
and a.department_id like concat ('%', #{departmentId}, '%')
-
- and a.sign_date = #{signDate}
-
and a.duration like concat ('%', #{duration}, '%')
@@ -50,12 +47,6 @@
and a.product_service like concat ('%', #{productService}, '%')
-
- and a.payment_date = #{paymentDate}
-
-
- and a.performance_deadline = #{performanceDeadline}
-
and a.payment_address like concat ('%', #{paymentAddress}, '%')
diff --git a/flowable/pom.xml b/flowable/pom.xml
index edd8467..d11bf74 100644
--- a/flowable/pom.xml
+++ b/flowable/pom.xml
@@ -11,6 +11,10 @@
flowable
1.0.0-SNAPSHOT
+
+ UTF-8
+
+
com.dite.znpt
diff --git a/sip/pom.xml b/sip/pom.xml
new file mode 100644
index 0000000..7e62790
--- /dev/null
+++ b/sip/pom.xml
@@ -0,0 +1,52 @@
+
+
+ 4.0.0
+
+
+ com.dite.znpt
+ parent
+ 1.0.0-SNAPSHOT
+
+ sip
+ 1.0.0-SNAPSHOT
+
+
+ 17
+ 17
+ UTF-8
+
+
+
+ com.dite.znpt
+ core
+ 1.0.0-SNAPSHOT
+
+
+
+ org.projectlombok
+ lombok
+
+
+
+
+ javax.sip
+ jain-sip-ri
+ 1.3.0-91
+
+
+
+
+ org.dom4j
+ dom4j
+ 2.1.3
+
+
+ org.slf4j
+ log4j-over-slf4j
+ 1.7.36
+
+
+
+
\ No newline at end of file
diff --git a/sip/src/main/java/com/dite/znpt/monitor/config/MediaFormatConfig.java b/sip/src/main/java/com/dite/znpt/monitor/config/MediaFormatConfig.java
new file mode 100644
index 0000000..2c0dd0c
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/config/MediaFormatConfig.java
@@ -0,0 +1,30 @@
+package com.dite.znpt.monitor.config;
+
+import cn.hutool.core.collection.CollUtil;
+import com.dite.znpt.monitor.domain.vo.video.StreamMediaFormat;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.List;
+
+/**
+ * 媒体格式配置
+ *
+ * @author huise23
+ * @since 2023-07-31 09:08:05
+ */
+@Configuration
+public class MediaFormatConfig {
+
+ @Bean
+ public static List streamMediaFormatList() {
+ List formatList = CollUtil.newArrayList();
+ formatList.add(new StreamMediaFormat("flv",null,"1"));
+ formatList.add(new StreamMediaFormat("mp4",null,"0"));
+ formatList.add(new StreamMediaFormat("hls",null,"0"));
+ formatList.add(new StreamMediaFormat("webrtc",null,"1"));
+ return formatList;
+ }
+
+
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/constant/Constants.java b/sip/src/main/java/com/dite/znpt/monitor/constant/Constants.java
new file mode 100644
index 0000000..d1ee938
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/constant/Constants.java
@@ -0,0 +1,37 @@
+package com.dite.znpt.monitor.constant;
+
+/**
+ * @author yunp
+ * @since 2022/7/14
+ */
+public class Constants {
+ /**
+ * UTF-8 字符集
+ */
+ public static final String UTF8 = "UTF-8";
+
+ /**
+ * GBK 字符集
+ */
+ public static final String GBK = "GBK";
+
+ /**
+ * 路径拼接符 /
+ */
+ public static final String File_SEPARATOR = "/";
+
+ /**
+ * http请求
+ */
+ public static final String HTTP = "http://";
+
+ /**
+ * https请求
+ */
+ public static final String HTTPS = "https://";
+
+ /**
+ * 默认字符串分隔符
+ */
+ public static final String DEFAULT_DELIMITER = ",";
+}
\ No newline at end of file
diff --git a/sip/src/main/java/com/dite/znpt/monitor/constant/IotCacheConstants.java b/sip/src/main/java/com/dite/znpt/monitor/constant/IotCacheConstants.java
new file mode 100644
index 0000000..743494a
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/constant/IotCacheConstants.java
@@ -0,0 +1,37 @@
+package com.dite.znpt.monitor.constant;
+
+/**
+ * @author yunp
+ * @since 2022/8/4
+ * @description 缓存key定义:key全部以iot开头
+ */
+public class IotCacheConstants {
+
+ /**
+ * 参数管理 cache key
+ */
+ public static final String SYS_CONFIG_KEY = "sys_config:";
+
+ /**
+ * 字典管理 cache key
+ */
+ public static final String SYS_DICT_KEY = "sys_dict:";
+
+ /**
+ * 图标库 cache key
+ */
+ public static final String SYS_ICON_KEY = "sys_icon";
+
+ private static final String IOT_DEVICE_VIDEO_PREFIX = "vs_device_video:";
+
+ public static String getIotDeviceVideoKey(String deviceCode){
+ return IOT_DEVICE_VIDEO_PREFIX + deviceCode;
+ }
+
+ private final static String CLIENT_TRANSACTION_CACHE_PREFIX = "IOT_CLIENT_TRANSACTION_CACHE:";
+
+ public static String getClientTransactionCacheKey(String ssrc){
+ return CLIENT_TRANSACTION_CACHE_PREFIX + ssrc;
+ }
+
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/constant/IotDictConstants.java b/sip/src/main/java/com/dite/znpt/monitor/constant/IotDictConstants.java
new file mode 100644
index 0000000..4e3d10d
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/constant/IotDictConstants.java
@@ -0,0 +1,20 @@
+package com.dite.znpt.monitor.constant;
+
+/**
+ * @author yunp
+ * @since 2022/8/4
+ * @description 字典类型定义
+ */
+public class IotDictConstants {
+
+ /**
+ * 设备状态-在线
+ */
+ public static final String IOT_DEVICE_STATUS_ONLINE = "2";
+
+ /**
+ * 设备状态-离线
+ */
+ public static final String IOT_DEVICE_STATUS_OFFLINE = "3";
+
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/constant/IotRespMessage.java b/sip/src/main/java/com/dite/znpt/monitor/constant/IotRespMessage.java
new file mode 100644
index 0000000..7cdf9eb
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/constant/IotRespMessage.java
@@ -0,0 +1,113 @@
+package com.dite.znpt.monitor.constant;
+
+/**
+ * @author yunp
+ * @since 2022/8/4
+ * @description 响应文案定义
+ */
+public class IotRespMessage {
+
+ public static final String UNKNOWN_FAIL = "未知错误";
+
+ public static final String ID_NOT_FOUND = "数据不存在";
+
+ public static final String PARAMETER_ERROR = "参数有误";
+
+ public static final String NO_PERMISSION = "没有访问权限";
+
+ public static final String PARENT_AREA_NOT_FOUND = "上级分区不存在";
+
+ public static final String CAR_TYPE_HAS_CARS = "该车型下仍有车辆,无法删除";
+
+ public static final String CAR_BRAND_HAS_CARS = "该品牌下仍有车辆,无法删除";
+
+ public static final String CAR_PLATE_NUMBER_EXIST = "该车牌号车辆已存在";
+
+ public static final String CAR_PLATE_NUMBER_NOT_EXIST = "该车牌号车辆不存在";
+
+ public static final String CAR_HAS_BIND_TAG_OR_SPEED_MONITOR = "车辆已绑定车载标签或速度检测仪,禁止删除";
+
+ public static final String CAR_FREIGHT_NOT_EXIST = "货物不存在";
+
+ public static final String CAR_HAS_BIND_ALARM_TEMPLATE = "该车辆已绑定其他告警模板";
+
+ public static final String USER_HAS_BIND_ALARM_TEMPLATE = "该人员已绑定其他告警模板";
+
+ public static final String REPETITION_ALARM_FOR_AREA = "该厂区分区下已有同类型告警,无法重复添加";
+
+ public static final String REPETITION_ALARM_NOTIFY_CONFIG = "已存在相同部门层级的告警消息推送配置";
+
+ public static final String DEVICE_TERMINAL_HAS_BEEN_BIND = "该标签卡已被其他人绑定";
+
+ public static final String DEVICE_TERMINAL_TYPE_ERROR = "标签卡类型有误";
+
+ public static final String DEVICE_TERMINAL_NOT_FOUND_OR_STATUS_ERROR = "标签卡未找到或状态异常";
+
+ public static final String DEVICE_CANNOT_EDIT = "设备未启用或已停用才可编辑";
+
+ public static final String VIDEO_DEVICE_CANNOT_DELETE = "视频设备禁止删除";
+
+ public static final String DEVICE_CANNOT_DELETE = "未启用的设备才可删除";
+
+ public static final String DEVICE_HAS_BIND_TO_GROUP = "设备已经绑定至该分组";
+
+ public static final String DEVICE_VIDEO_CANNOT_DELETE = "禁止删除在线视频设备";
+
+ public static final String DEVICE_VIDEO_CANNOT_SYNC = "禁止更新离线视频设备";
+
+ public static final String DEVICE_INACTIVE = "设备未启用";
+
+ public static final String CODE_HAS_BEEN_USED = "编号已被占用";
+
+ public static final String NAME_HAS_BEEN_USED = "名称已被占用";
+
+ public static final String FLAG_HAS_BEEN_USED = "标识已被占用";
+
+ public static final String GROUP_HAS_CHILD_CANNOT_REMOVE = "分组有下级分组,无法删除";
+
+ public static final String GROUP_HAS_DEVICE_CANNOT_REMOVE = "分组下有绑定设备,无法删除";
+
+ public static final String PRODUCT_PUBLISH_CANNOT_DELETE = "该产品已发布,不可删除";
+
+ public static final String PRODUCT_HAS_DEVICE_CANNOT_REMOVE = "产品下存在设备关联,需删除设备后进行操作";
+
+ public static final String MSG_PROTOCOL_PUBLISH_CANNOT_DELETE = "消息协议未发布,发布协议后操作";
+
+ public static final String CATEGORY_CANNOT_DELETE = "该产品分类信息已被产品关联,不可删除";
+
+ public static final String SCENE_CANNOT_DELETE = "该场景信息已被产品关联,不可删除";
+
+ public static final String SWITCH_PARAM_HAS_BEEN_USED = "该参数在设备服务中只能定义一个";
+
+ public static final String CONFIG_CANNOT_DELETE = "该配置已被通知模板关联,不可删除, 请取消关联后重试。";
+
+ public static final String TEMPLATE_CANNOT_DELETE = "该通知模板已被场景联动关联,不可删除, 请取消关联后操作。";
+
+ public static final String PROTOCOL_CANNOT_DELETE_BY_PUBLISHED = "当前协议状态为已发布,不可删除.";
+
+ public static final String PROTOCOL_CANNOT_DELETE_WITH_PRODUCT = "该协议已被产品关联,不可删除,请删除关联后操作!";
+
+ public static final String PROTOCOL_CANNOT_UN_PUBLISH = "协议已被产品发布,不可取消!";
+
+ public static final String PROTOCOL_TYPE_CANNOT_NULL = "协议类型不能为空";
+
+ public static final String PROTOCOL_CLASS_NAME_CANNOT_EMPTY = "协议类型为Jar或者Local类型时,必须指定协议类名.";
+
+ public static final String PROTOCOL_FILE_PATH_CANNOT_EMPTY = "协议类型为Jar或者Local类型时,必须上传或者指定协议文件路径.";
+
+ public static final String DATA_ILLEGAL = "数据非法";
+
+ public static final String IMPORT_ERROR = "导入出错";
+
+ public static final String COMMON_DEVICE_ATTR_DUPLICATE_ERROR = "订阅的通用设备点位全局不唯一";
+
+ public static final String PROTOCOL_NOT_EXISTS = "协议不存在";
+
+ public static final String RULE_NOT_EXISTS = "上报规则不存在";
+
+ public static final String DEVICE_NOT_EXISTS = "设备不存在";
+
+ public static final String DATA_DATA_TREND_TIME_TYPE_NOT_EXISTS = "设备数据趋势时间类型不存在";
+ public static final String DATA_DATA_TREND_DATA_TYPE_NOT_EXISTS = "设备数据趋势数据类型不存在";
+ public static final String CRON_ERROR = "cron表达式输入错误:";
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/constant/dict/CameraType.java b/sip/src/main/java/com/dite/znpt/monitor/constant/dict/CameraType.java
new file mode 100644
index 0000000..a05e191
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/constant/dict/CameraType.java
@@ -0,0 +1,32 @@
+package com.dite.znpt.monitor.constant.dict;
+
+/**
+ * 摄像头类型
+ *
+ * @author huise23
+ * @since 2023-07-28 15:30:10
+ */
+public enum CameraType implements ValueAndLabel {
+
+ UNKNOWN("0","未知"),
+ BALLHEAD("1","球机");
+
+ private final String value;
+ private final String label;
+
+ CameraType(String value, String label) {
+ this.value = value;
+ this.label = label;
+ }
+
+ @Override
+ public String getValue() {
+ return value;
+ }
+
+ @Override
+ public String getLabel() {
+ return label;
+ }
+
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/constant/dict/DeviceStatus.java b/sip/src/main/java/com/dite/znpt/monitor/constant/dict/DeviceStatus.java
new file mode 100644
index 0000000..2101f2b
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/constant/dict/DeviceStatus.java
@@ -0,0 +1,34 @@
+package com.dite.znpt.monitor.constant.dict;
+
+/**
+ * 设备状态
+ *
+ * @author huise23
+ * @since 2023-07-28 15:30:10
+ */
+public enum DeviceStatus implements ValueAndLabel {
+
+ INACTIV("1", "未启用"),
+ ONLINE("2", "在线"),
+ OFFLINE("3", "离线"),
+ STOP("4", "停用");
+
+ private final String value;
+ private final String label;
+
+ DeviceStatus(String value, String label) {
+ this.value = value;
+ this.label = label;
+ }
+
+ @Override
+ public String getValue() {
+ return value;
+ }
+
+ @Override
+ public String getLabel() {
+ return label;
+ }
+
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/constant/dict/SipTransferMode.java b/sip/src/main/java/com/dite/znpt/monitor/constant/dict/SipTransferMode.java
new file mode 100644
index 0000000..e621c06
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/constant/dict/SipTransferMode.java
@@ -0,0 +1,26 @@
+package com.dite.znpt.monitor.constant.dict;
+
+public enum SipTransferMode implements ValueAndLabel {
+
+ UDP("UDP","UDP"),
+ TCP("TCP","TCP");
+
+ private final String value;
+ private final String label;
+
+ SipTransferMode(String value, String label) {
+ this.value = value;
+ this.label = label;
+ }
+
+ @Override
+ public String getValue() {
+ return value;
+ }
+
+ @Override
+ public String getLabel() {
+ return label;
+ }
+
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/constant/dict/StreamTransferMode.java b/sip/src/main/java/com/dite/znpt/monitor/constant/dict/StreamTransferMode.java
new file mode 100644
index 0000000..fea526a
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/constant/dict/StreamTransferMode.java
@@ -0,0 +1,27 @@
+package com.dite.znpt.monitor.constant.dict;
+
+public enum StreamTransferMode implements ValueAndLabel {
+
+ UDP("UDP","UDP"),
+ TCP_ACTIVE("TCP-ACTIVE","TCP主动"),
+ TCP_PASSIVE("TCP-PASSIVE", "TCP被动");
+
+ private final String value;
+ private final String label;
+
+ StreamTransferMode(String value, String label) {
+ this.value = value;
+ this.label = label;
+ }
+
+ @Override
+ public String getValue() {
+ return value;
+ }
+
+ @Override
+ public String getLabel() {
+ return label;
+ }
+
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/constant/dict/ValueAndLabel.java b/sip/src/main/java/com/dite/znpt/monitor/constant/dict/ValueAndLabel.java
new file mode 100644
index 0000000..88b5b1b
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/constant/dict/ValueAndLabel.java
@@ -0,0 +1,14 @@
+package com.dite.znpt.monitor.constant.dict;
+
+
+/**
+ * 字典常量接口
+ *
+ * @author huise23
+ * @since 2023-07-28 15:28:55
+ */
+public interface ValueAndLabel {
+ String getValue();
+ String getLabel();
+
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/constant/dict/YesOrNo.java b/sip/src/main/java/com/dite/znpt/monitor/constant/dict/YesOrNo.java
new file mode 100644
index 0000000..62889fd
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/constant/dict/YesOrNo.java
@@ -0,0 +1,32 @@
+package com.dite.znpt.monitor.constant.dict;
+
+/**
+ * YesOrNo
+ *
+ * @author huise23
+ * @since 2023-07-28 15:30:10
+ */
+public enum YesOrNo implements ValueAndLabel {
+
+ YES("Y","是"),
+ NO("N", "否");
+
+ private final String value;
+ private final String label;
+
+ YesOrNo(String value, String label) {
+ this.value = value;
+ this.label = label;
+ }
+
+ @Override
+ public String getValue() {
+ return value;
+ }
+
+ @Override
+ public String getLabel() {
+ return label;
+ }
+
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/domain/CustomFunction.java b/sip/src/main/java/com/dite/znpt/monitor/domain/CustomFunction.java
new file mode 100644
index 0000000..bf145cc
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/domain/CustomFunction.java
@@ -0,0 +1,14 @@
+package com.dite.znpt.monitor.domain;
+
+/**
+ * @Author: cuizhibin
+ * @Date: 2023/1/16 14:36:36
+ * @Description:
+ */
+public interface CustomFunction {
+ /**
+ * 执行的方法
+ * @return
+ */
+ T get();
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/domain/entity/DeviceVideoChannelEntity.java b/sip/src/main/java/com/dite/znpt/monitor/domain/entity/DeviceVideoChannelEntity.java
new file mode 100644
index 0000000..4b263aa
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/domain/entity/DeviceVideoChannelEntity.java
@@ -0,0 +1,124 @@
+package com.dite.znpt.monitor.domain.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/11 17:29
+ * @Description:
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("vs_device_video_channel")
+@ApiModel(value="DeviceVideoChannelEntity", description="视频通道表")
+public class DeviceVideoChannelEntity implements Serializable {
+
+ private static final long serialVersionUID = -4175177624487756818L;
+
+ @ApiModelProperty(value = "主键id")
+ @TableId(value = "channel_id", type = IdType.AUTO)
+ private Long channelId;
+
+ @ApiModelProperty(value = "视频设备id")
+ private Long videoId;
+
+ @ApiModelProperty(value = "通道国标编号")
+ private String channelCode;
+
+ @ApiModelProperty(value = "通道名")
+ private String channelName;
+
+ @ApiModelProperty(value = "生产厂商")
+ private String manufacture;
+
+ @ApiModelProperty(value = "型号")
+ private String model;
+
+ @ApiModelProperty(value = "设备归属")
+ private String owner;
+
+ @ApiModelProperty(value = "行政区域")
+ private String civilCode;
+
+ @ApiModelProperty(value = "警区")
+ private String block;
+
+ @ApiModelProperty(value = "安装位置")
+ private String address;
+
+ @ApiModelProperty(value = "是否有子设备 1有, 0没有")
+ private int parental;
+
+ @ApiModelProperty(value = "父级id")
+ private String parentId;
+
+ @ApiModelProperty(value = "信令安全模式 缺省为0; 0:不采用; 2: S/MIME签名方式; 3: S/ MIME加密签名同时采用方式; 4:数字摘要方式")
+ private int safetyWay;
+
+ @ApiModelProperty(value = "注册方式 缺省为1;1:符合IETFRFC3261标准的认证注册模 式; 2:基于口令的双向认证注册模式; 3:基于数字证书的双向认证注册模式")
+ private int registerWay;
+
+ @ApiModelProperty("证书序列号")
+ private String certNum;
+
+ @ApiModelProperty("证书有效标识 缺省为0;证书有效标识:0:无效1: 有效")
+ private int certifiable;
+
+ @ApiModelProperty("证书无效原因码")
+ private int errCode;
+
+ @ApiModelProperty( "证书终止有效期")
+ private String endTime;
+
+ @ApiModelProperty("保密属性 缺省为0; 0:不涉密, 1:涉密")
+ private String secrecy;
+
+ @ApiModelProperty("IP地址")
+ private String ipAddress;
+
+ @ApiModelProperty("端口号")
+ private int port;
+
+ @ApiModelProperty("密码")
+ private String password;
+
+ @ApiModelProperty("摄像头类型")
+ private String cameraType;
+
+ @ApiModelProperty("云台控制")
+ private String ptzControl;
+
+ @ApiModelProperty(value = "状态")
+ private String status;
+
+ @ApiModelProperty("经度")
+ private double longitude;
+
+ @ApiModelProperty("纬度")
+ private double latitude;
+
+ @ApiModelProperty(value = "备注")
+ private String remark;
+
+ @ApiModelProperty("创建时间")
+ private LocalDateTime createTime;
+
+ @ApiModelProperty("创建人id")
+ @TableField(fill = FieldFill.INSERT)
+ private Long createBy;
+
+ @ApiModelProperty("更新时间")
+ private LocalDateTime updateTime;
+
+ @ApiModelProperty("更新人id")
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ private Long updateBy;
+
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/domain/entity/DeviceVideoEntity.java b/sip/src/main/java/com/dite/znpt/monitor/domain/entity/DeviceVideoEntity.java
new file mode 100644
index 0000000..9b35a56
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/domain/entity/DeviceVideoEntity.java
@@ -0,0 +1,96 @@
+package com.dite.znpt.monitor.domain.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/11 10:24
+ * @Description:
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("vs_device_video")
+@ApiModel(value="DeviceVideoEntity", description="视频设备表")
+public class DeviceVideoEntity implements Serializable {
+
+ private static final long serialVersionUID = -182441901641147882L;
+
+ @ApiModelProperty(value = "主键id")
+ @TableId(value = "video_id", type = IdType.AUTO)
+ private Long videoId;
+
+ @ApiModelProperty(value = "视频设备国标编码")
+ private String videoCode;
+
+ @ApiModelProperty(value = "视频设备名称")
+ private String videoName;
+
+ @ApiModelProperty(value = "生产厂商")
+ private String manufacturer;
+
+ @ApiModelProperty(value = "型号")
+ private String model;
+
+ @ApiModelProperty(value = "固件版本")
+ private String firmware;
+
+ @ApiModelProperty(value = "传输协议(UDP/TCP),默认UDP")
+ private String transport;
+
+ @ApiModelProperty(value = "数据流传输模式(默认UDP)")
+ private String streamMode;
+
+ @ApiModelProperty(value = "设备状态")
+ private String status;
+
+ @ApiModelProperty(value = "注册时间")
+ private LocalDateTime registerTime;
+
+ @ApiModelProperty(value = "心跳时间")
+ private LocalDateTime KeepaliveTime;
+
+ @ApiModelProperty("通道个数")
+ private int channelCount;
+
+ @ApiModelProperty(value = "ip")
+ private String ip;
+
+ @ApiModelProperty(value = "端口")
+ private Integer port;
+
+ @ApiModelProperty(value = "地址")
+ private String hostAddress;
+
+ @ApiModelProperty(value = "注册有效期")
+ private Integer expires;
+
+ @ApiModelProperty(value = "符集, 支持 UTF-8 与 GB2312")
+ private String charset;
+
+ @ApiModelProperty(value = "产品id")
+ private Long productId;
+
+ @ApiModelProperty(value = "备注")
+ private String remark;
+
+ @ApiModelProperty("创建时间")
+ private LocalDateTime createTime;
+
+ @ApiModelProperty("创建人id")
+ @TableField(fill = FieldFill.INSERT)
+ private Long createBy;
+
+ @ApiModelProperty("更新时间")
+ private LocalDateTime updateTime;
+
+ @ApiModelProperty("更新人id")
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ private Long updateBy;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/domain/entity/IpConfigEntity.java b/sip/src/main/java/com/dite/znpt/monitor/domain/entity/IpConfigEntity.java
new file mode 100644
index 0000000..04c67b4
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/domain/entity/IpConfigEntity.java
@@ -0,0 +1,35 @@
+package com.dite.znpt.monitor.domain.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+
+/**
+ * @Date: 2023/09/05 16:39
+ * @Description: 监控设备IP配置表实体类
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("vs_ip_config")
+@ApiModel(value="VsIpConfigEntity对象", description="监控设备IP配置表")
+public class IpConfigEntity implements Serializable {
+
+ @ApiModelProperty("${column.comment}")
+ @TableId(type = IdType.AUTO)
+ private Long configId;
+
+ @ApiModelProperty("ip地址")
+ private String ip;
+
+ @ApiModelProperty("ip地址前三位")
+ private String ipTopThree;
+
+
+}
+
diff --git a/sip/src/main/java/com/dite/znpt/monitor/domain/req/MonitorConfigAddReq.java b/sip/src/main/java/com/dite/znpt/monitor/domain/req/MonitorConfigAddReq.java
new file mode 100644
index 0000000..be2a92e
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/domain/req/MonitorConfigAddReq.java
@@ -0,0 +1,14 @@
+package com.dite.znpt.monitor.domain.req;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @Date:2023/9/5 16:19
+ * @Description: 视频服务配置新增对象
+ */
+@Data
+public class MonitorConfigAddReq {
+ private List ipAddresses;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/domain/req/VideoInfoReq.java b/sip/src/main/java/com/dite/znpt/monitor/domain/req/VideoInfoReq.java
new file mode 100644
index 0000000..0dc809c
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/domain/req/VideoInfoReq.java
@@ -0,0 +1,23 @@
+package com.dite.znpt.monitor.domain.req;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 查询视频信息参数
+ *
+ * @author huise23
+ * @since 2024-12-03 14:03:29
+ */
+@Data
+public class VideoInfoReq implements Serializable {
+
+ @ApiModelProperty(value = "视频对接方式 1.摄像头直连 2.级联")
+ private Integer videoConnection;
+
+ @ApiModelProperty(value = "级联分隔符(默认/)")
+ private String cascadeSeparator = "/";
+
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/domain/resp/DeviceVideoResp.java b/sip/src/main/java/com/dite/znpt/monitor/domain/resp/DeviceVideoResp.java
new file mode 100644
index 0000000..f8a76ae
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/domain/resp/DeviceVideoResp.java
@@ -0,0 +1,19 @@
+package com.dite.znpt.monitor.domain.resp;
+
+import com.dite.znpt.monitor.domain.entity.DeviceVideoEntity;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @Date:2023/9/7 10:26
+ * @Description:
+ */
+@Data
+public class DeviceVideoResp extends DeviceVideoEntity {
+ @ApiModelProperty(value = "设备状态label")
+ private String statusLabel;
+ @ApiModelProperty(value = "流传输模式label")
+ private String streamModeLabel;
+ @ApiModelProperty(value = "传输模式label")
+ private String transportLabel;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/domain/resp/VideoInfoResp.java b/sip/src/main/java/com/dite/znpt/monitor/domain/resp/VideoInfoResp.java
new file mode 100644
index 0000000..7ba594c
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/domain/resp/VideoInfoResp.java
@@ -0,0 +1,58 @@
+package com.dite.znpt.monitor.domain.resp;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 查询视频信息返回信息
+ *
+ * @author huise23
+ * @since 2024-12-03 14:03:29
+ */
+@Data
+public class VideoInfoResp implements Serializable {
+
+ @ApiModelProperty(value = "视频设备id")
+ private Long videoId;
+
+ @ApiModelProperty(value = "视频设备名称")
+ private String videoName;
+
+ @ApiModelProperty(value = "通道id")
+ private Long channelId;
+
+ @ApiModelProperty(value = "国标编码")
+ private String channelCode;
+
+ @ApiModelProperty(value = "通道名称")
+ private String channelName;
+
+ @ApiModelProperty(value = "生产厂商")
+ private String manufacture;
+
+ @ApiModelProperty(value = "型号")
+ private String model;
+
+ @ApiModelProperty(value = "安装位置")
+ private String address;
+
+ @ApiModelProperty("IP地址")
+ private String ipAddress;
+
+ @ApiModelProperty("端口号")
+ private int port;
+
+ @ApiModelProperty(value = "云台控制label")
+ private String ptzControl;
+
+ @ApiModelProperty("经度")
+ private double longitude;
+
+ @ApiModelProperty("纬度")
+ private double latitude;
+
+ @ApiModelProperty(value = "状态 DeviceStatus")
+ private String status;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/DeviceVideoChannelEditReq.java b/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/DeviceVideoChannelEditReq.java
new file mode 100644
index 0000000..1ec735a
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/DeviceVideoChannelEditReq.java
@@ -0,0 +1,34 @@
+package com.dite.znpt.monitor.domain.vo.video;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/11 18:12
+ * @Description:
+ */
+@Data
+@ApiModel("视频通道编辑请求")
+public class DeviceVideoChannelEditReq implements Serializable {
+
+ private static final long serialVersionUID = 719557164910393807L;
+
+ @ApiModelProperty(value = "通道名称")
+ private String channelName;
+
+ @ApiModelProperty(value = "安装位置")
+ private String address;
+
+ @ApiModelProperty(value = "摄像头类型")
+ private String cameraType;
+
+ @ApiModelProperty(value = "云台控制,Y表示是,N表示否")
+ private String ptzControl;
+
+ @ApiModelProperty(value = "描述")
+ private String remark;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/DeviceVideoChannelListResp.java b/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/DeviceVideoChannelListResp.java
new file mode 100644
index 0000000..31234fb
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/DeviceVideoChannelListResp.java
@@ -0,0 +1,55 @@
+package com.dite.znpt.monitor.domain.vo.video;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/11 18:12
+ * @Description:
+ */
+@Data
+@ApiModel("视频通道列表响应")
+public class DeviceVideoChannelListResp implements Serializable {
+
+ private static final long serialVersionUID = -8053965410352257803L;
+
+ @ApiModelProperty(value = "主键id")
+ private Long channelId;
+
+ @ApiModelProperty(value = "所属产品id")
+ private Long productId;
+
+ @ApiModelProperty(value = "通道国标编码")
+ private String channelCode;
+
+ @ApiModelProperty(value = "通道名称")
+ private String channelName;
+
+ @ApiModelProperty(value = "安装位置")
+ private String address;
+
+ @ApiModelProperty(value = "摄像头类型label")
+ private String cameraType;
+
+ @ApiModelProperty(value = "摄像头类型")
+ private String cameraTypeLabel;
+
+ @ApiModelProperty(value = "云台控制label")
+ private String ptzControl;
+
+ @ApiModelProperty(value = "云台控制,Y表示是,N表示否")
+ private String ptzControlLabel;
+
+ @ApiModelProperty(value = "状态")
+ private String status;
+
+ @ApiModelProperty(value = "状态label")
+ private String statusLabel;
+
+ @ApiModelProperty(value = "描述")
+ private String remark;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/DeviceVideoChannelResp.java b/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/DeviceVideoChannelResp.java
new file mode 100644
index 0000000..1f22085
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/DeviceVideoChannelResp.java
@@ -0,0 +1,43 @@
+package com.dite.znpt.monitor.domain.vo.video;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/11 18:12
+ * @Description:
+ */
+@Data
+@ApiModel("视频通道响应")
+public class DeviceVideoChannelResp implements Serializable {
+
+ private static final long serialVersionUID = 1140851083577845760L;
+
+ @ApiModelProperty(value = "主键id")
+ private Long channelId;
+
+ @ApiModelProperty(value = "通道国标编码")
+ private String channelCode;
+
+ @ApiModelProperty(value = "通道名称")
+ private String channelName;
+
+ @ApiModelProperty(value = "安装位置")
+ private String address;
+
+ @ApiModelProperty(value = "摄像头类型")
+ private String cameraType;
+
+ @ApiModelProperty(value = "云台控制,Y表示是,N表示否")
+ private String ptzControl;
+
+ @ApiModelProperty(value = "状态")
+ private String status;
+
+ @ApiModelProperty(value = "描述")
+ private String remark;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/DeviceVideoEditReq.java b/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/DeviceVideoEditReq.java
new file mode 100644
index 0000000..a1f2b8e
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/DeviceVideoEditReq.java
@@ -0,0 +1,29 @@
+package com.dite.znpt.monitor.domain.vo.video;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/11 18:13
+ * @Description:
+ */
+@Data
+@ApiModel("视频设备编辑请求参数")
+public class DeviceVideoEditReq implements Serializable {
+
+ private static final long serialVersionUID = -3387666090991548317L;
+
+ @ApiModelProperty(value = "设备名称")
+ private String videoName;
+
+ @ApiModelProperty(value = "所属产品")
+ private Long productId;
+
+ @ApiModelProperty(value = "说明")
+ private String remark;
+
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/DeviceVideoListResp.java b/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/DeviceVideoListResp.java
new file mode 100644
index 0000000..026f873
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/DeviceVideoListResp.java
@@ -0,0 +1,74 @@
+package com.dite.znpt.monitor.domain.vo.video;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/11 18:13
+ * @Description:
+ */
+@Data
+@ApiModel("视频设备列表响应")
+public class DeviceVideoListResp implements Serializable {
+
+ private static final long serialVersionUID = -5568664011265192343L;
+
+ @ApiModelProperty(value = "主键id")
+ private Long videoId;
+
+ @ApiModelProperty(value = "视频设备国标编码")
+ private String videoCode;
+
+ @ApiModelProperty(value = "视频设备名称")
+ private String videoName;
+
+ @ApiModelProperty(value = "传输模式")
+ private String transport;
+
+ @ApiModelProperty(value = "传输模式label")
+ private String transportLabel;
+
+ @ApiModelProperty(value = "流传输模式")
+ private String streamMode;
+
+ @ApiModelProperty(value = "流传输模式label")
+ private String streamModeLabel;
+
+ @ApiModelProperty(value = "通道数量")
+ private Integer channelCount;
+
+ @ApiModelProperty(value = "设备状态")
+ private String status;
+
+ @ApiModelProperty(value = "设备状态label")
+ private String statusLabel;
+
+ @ApiModelProperty(value = "设备ip")
+ private String ip;
+
+ @ApiModelProperty(value = "设备端口")
+ private String port;
+
+ @ApiModelProperty(value = "设备地址(ip+端口)")
+ private String hostAddress;
+
+ @ApiModelProperty(value = "生产厂商")
+ private String manufacturer;
+
+ @ApiModelProperty(value = "备注")
+ private String remark;
+
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @ApiModelProperty(value = "创建时间")
+ private LocalDateTime createTime;
+
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @ApiModelProperty(value = "心跳时间")
+ private LocalDateTime keepAliveTime;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/DeviceVideoNumResp.java b/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/DeviceVideoNumResp.java
new file mode 100644
index 0000000..f56b8c1
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/DeviceVideoNumResp.java
@@ -0,0 +1,24 @@
+package com.dite.znpt.monitor.domain.vo.video;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/16 9:34
+ * @Description:
+ */
+@Data
+@ApiModel("视频设备数量响应")
+public class DeviceVideoNumResp {
+
+ @ApiModelProperty(value = "设备总数量")
+ private Long allDevice;
+
+ @ApiModelProperty(value = "设备在线数量")
+ private Long onlineDevice;
+
+ @ApiModelProperty(value = "设备离线数量")
+ private Long offlineDevice;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/StreamMediaFormat.java b/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/StreamMediaFormat.java
new file mode 100644
index 0000000..5c5f457
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/StreamMediaFormat.java
@@ -0,0 +1,77 @@
+package com.dite.znpt.monitor.domain.vo.video;
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.dite.znpt.monitor.media.zlm.dto.ServerConfig;
+import com.dite.znpt.monitor.media.zlm.enums.MediaFormatType;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/11 10:25
+ * @Description:
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@ApiModel(value = "StreamMediaFormat对象", description = "流媒体格式")
+public class StreamMediaFormat implements Serializable {
+
+ private static final long serialVersionUID = -4177962876536716643L;
+
+ @ApiModelProperty(value = "流媒体格式")
+ private String mediaFormat;
+
+ @ApiModelProperty(value = "端口")
+ private Integer port;
+
+ @ApiModelProperty(value = "是否开启tls,1表示ture,0表示false")
+ private String openTls;
+
+ @TableField(exist = false)
+ @ApiModelProperty(value = "WebSocket播放地址")
+ private String wsUrl;
+
+ @TableField(exist = false)
+ @ApiModelProperty(value = "Http播放地址")
+ private String httpUrl;
+
+ @TableField(exist = false)
+ @ApiModelProperty(value = "WebSocket播放地址")
+ private String wssUrl;
+
+ @TableField(exist = false)
+ @ApiModelProperty(value = "Http播放地址")
+ private String httpsUrl;
+
+ @TableField(exist = false)
+ @ApiModelProperty(value = "相对播放地址")
+ private String relativePath;
+
+ public StreamMediaFormat(String mediaFormat,Integer port,String openTls){
+ this.mediaFormat = mediaFormat;
+ this.port = port;
+ this.openTls = openTls;
+ }
+
+ public void generateUrl(String host, String streamId, ServerConfig config, String mediaRouter) {
+ if("webrtc".equals(this.mediaFormat)){
+ this.httpUrl = StrUtil.format("http://{}:{}/index/api/webrtc?app=rtp&stream={}&type=play", host, config.getHttpPort(), streamId);
+ this.httpsUrl = StrUtil.format("https://{}:{}/index/api/webrtc?app=rtp&stream={}&type=play", host, config.getHttpSslPort(), streamId);
+ this.relativePath = StrUtil.format("{}/index/api/webrtc?app=rtp&stream={}&type=play", mediaRouter, streamId);
+ return;
+ }
+ String suffix = MediaFormatType.getSuffix(this.mediaFormat);
+ if (config.getHttpSslPort() != null && config.getHttpSslPort() > 0) {
+ this.wssUrl = StrUtil.format("wss://{}:{}/rtp/{}{}", host, config.getHttpSslPort(), streamId, suffix);
+ this.httpsUrl = StrUtil.format("https://{}:{}/rtp/{}{}", host, config.getHttpSslPort(), streamId, suffix);
+ }
+ this.wsUrl = StrUtil.format("ws://{}:{}/rtp/{}{}", host, config.getHttpPort(), streamId, suffix);
+ this.httpUrl = StrUtil.format("http://{}:{}/rtp/{}{}", host, config.getHttpPort(), streamId, suffix);
+ this.relativePath = StrUtil.format("{}/rtp/{}{}", mediaRouter, streamId, suffix);
+ }
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/StreamMediaFormatReq.java b/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/StreamMediaFormatReq.java
new file mode 100644
index 0000000..d3ce278
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/StreamMediaFormatReq.java
@@ -0,0 +1,28 @@
+package com.dite.znpt.monitor.domain.vo.video;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/11 14:40
+ * @Description:
+ */
+@Data
+@ApiModel("流媒体格式请求")
+public class StreamMediaFormatReq implements Serializable {
+
+ private static final long serialVersionUID = 6627383994019834279L;
+
+ @ApiModelProperty(value = "流媒体格式")
+ private String mediaFormat;
+
+ @ApiModelProperty(value = "端口")
+ private Integer port;
+
+ @ApiModelProperty(value = "是否开启TLS,1表示true,0表示false")
+ private String openTls;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/StreamMediaFormatResp.java b/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/StreamMediaFormatResp.java
new file mode 100644
index 0000000..ad9304b
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/StreamMediaFormatResp.java
@@ -0,0 +1,31 @@
+package com.dite.znpt.monitor.domain.vo.video;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/11 14:40
+ * @Description:
+ */
+@Data
+@ApiModel("流媒体格式响应")
+public class StreamMediaFormatResp implements Serializable {
+
+ private static final long serialVersionUID = -5714327034173930078L;
+
+ @ApiModelProperty(value = "流媒体格式主键")
+ private Long formatId;
+
+ @ApiModelProperty(value = "流媒体格式")
+ private String mediaFormat;
+
+ @ApiModelProperty(value = "端口")
+ private Integer port;
+
+ @ApiModelProperty(value = "是否开启TLS,1表示true,0表示false")
+ private String openTls;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/StreamMediaServerConfigReq.java b/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/StreamMediaServerConfigReq.java
new file mode 100644
index 0000000..36c15fd
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/StreamMediaServerConfigReq.java
@@ -0,0 +1,59 @@
+package com.dite.znpt.monitor.domain.vo.video;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/11 14:16
+ * @Description:
+ */
+@Data
+@ApiModel("流媒体服务配置请求")
+public class StreamMediaServerConfigReq implements Serializable {
+
+ private static final long serialVersionUID = -1228005085084886474L;
+
+ @NotNull(message = "流媒体名称不能为空")
+ @ApiModelProperty(value = "流媒体名称")
+ private String mediaName;
+
+ @ApiModelProperty(value = "流媒体服务")
+ private String mediaService;
+
+ @ApiModelProperty(value = "公网 HOST")
+ private String publicHost;
+
+ @ApiModelProperty(value = "API HOST")
+ private String apiHost;
+
+ @ApiModelProperty(value = "API 端口")
+ private Integer apiPort;
+
+ @ApiModelProperty(value = "密钥")
+ private Integer secretKey;
+
+ @ApiModelProperty(value = "流ID前缀")
+ private String streamPrefix;
+
+ @ApiModelProperty(value = "RTP IP")
+ private String rtpHost;
+
+ @ApiModelProperty(value = "RTP 端口")
+ private Integer rtpPort;
+
+ @ApiModelProperty(value = "动态端口起始值")
+ private Integer dynamicPortStart;
+
+ @ApiModelProperty(value = "动态端口结束值")
+ private Integer dynamicPortEnd;
+
+ @ApiModelProperty(value = "流媒体格式")
+ private List streamMediaFormatReqList;
+
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/StreamMediaServerConfigResp.java b/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/StreamMediaServerConfigResp.java
new file mode 100644
index 0000000..6e3b185
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/StreamMediaServerConfigResp.java
@@ -0,0 +1,60 @@
+package com.dite.znpt.monitor.domain.vo.video;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/11 14:16
+ * @Description:
+ */
+@Data
+@ApiModel("流媒体服务配置响应")
+public class StreamMediaServerConfigResp implements Serializable {
+
+ private static final long serialVersionUID = 3464085768355214710L;
+
+ @ApiModelProperty(value = "'流媒体配置主键'")
+ private Long configId;
+
+ @ApiModelProperty(value = "'流媒体名称'")
+ private String mediaName;
+
+ @ApiModelProperty(value = "流媒体服务")
+ private String mediaService;
+
+ @ApiModelProperty(value = "公网 HOST")
+ private String publicHost;
+
+ @ApiModelProperty(value = "API HOST")
+ private String apiHost;
+
+ @ApiModelProperty(value = "API 端口")
+ private Integer apiPort;
+
+ @ApiModelProperty(value = "密钥")
+ private String secretKey;
+
+ @ApiModelProperty(value = "流ID前缀")
+ private String streamPrefix;
+
+ @ApiModelProperty(value = "RTP IP")
+ private String rtpHost;
+
+ @ApiModelProperty(value = "RTP 端口")
+ private Integer rtpPort;
+
+ @ApiModelProperty(value = "动态端口起始值")
+ private Integer dynamicPortStart;
+
+ @ApiModelProperty(value = "动态端口结束值")
+ private Integer dynamicPortEnd;
+
+ @ApiModelProperty(value = "流媒体格式")
+ private List streamMediaFormatRespList;
+
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/VideoPayResp.java b/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/VideoPayResp.java
new file mode 100644
index 0000000..26809bc
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/domain/vo/video/VideoPayResp.java
@@ -0,0 +1,24 @@
+package com.dite.znpt.monitor.domain.vo.video;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Builder;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 视频播放响应
+ * @author huise23
+ * @since 2024-11-26 14:03:41
+ */
+@Data
+@Builder
+public class VideoPayResp {
+
+ @ApiModelProperty(value = "播放方式")
+ private String mediaType;
+
+ @ApiModelProperty(value = "流媒体播放地址")
+ private List streamMediaFormatList;
+
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/mapper/DeviceVideoChannelMapper.java b/sip/src/main/java/com/dite/znpt/monitor/mapper/DeviceVideoChannelMapper.java
new file mode 100644
index 0000000..2c211e8
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/mapper/DeviceVideoChannelMapper.java
@@ -0,0 +1,55 @@
+package com.dite.znpt.monitor.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.dite.znpt.monitor.domain.entity.DeviceVideoChannelEntity;
+import com.dite.znpt.monitor.domain.req.VideoInfoReq;
+import com.dite.znpt.monitor.domain.resp.VideoInfoResp;
+import com.dite.znpt.monitor.domain.vo.video.DeviceVideoChannelListResp;
+import com.dite.znpt.monitor.domain.vo.video.DeviceVideoChannelResp;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/11 18:08
+ * @Description:
+ */
+public interface DeviceVideoChannelMapper extends BaseMapper {
+
+ /**
+ * 查询视频通道列表
+ *
+ * @param videoId 视频id
+ * @param keyword 插叙条件
+ * @return {@link List< DeviceVideoChannelListResp>}
+ */
+ List selectDeviceVideoChannel(@Param("videoId") Long videoId, @Param("keyword") String keyword);
+
+ /**
+ * 查询所有视频通道列表
+ *
+ * @param keyword 插叙条件
+ * @return {@link List< DeviceVideoChannelListResp>}
+ */
+ List selectAllDeviceVideoChannel(@Param("keyword") String keyword);
+
+ /**
+ * 查询视频通道详情
+ *
+ * @param channelCode 通道code
+ * @return {@link DeviceVideoChannelResp}
+ */
+ DeviceVideoChannelResp getDeviceVideoChannelDetail(@Param("channelCode") String channelCode);
+
+ /**
+ * 查询通道及视频信息
+ *
+ * @param videoInfoReq 查询参数
+ * @return {@link VideoInfoResp }
+ * @author huise23
+ * @since 2024-12-03 13:54:52
+ */
+ List selectVideoInfoList(VideoInfoReq videoInfoReq);
+
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/mapper/DeviceVideoMapper.java b/sip/src/main/java/com/dite/znpt/monitor/mapper/DeviceVideoMapper.java
new file mode 100644
index 0000000..cc14697
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/mapper/DeviceVideoMapper.java
@@ -0,0 +1,24 @@
+package com.dite.znpt.monitor.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.dite.znpt.monitor.domain.entity.DeviceVideoEntity;
+import com.dite.znpt.monitor.domain.vo.video.DeviceVideoListResp;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/11 18:09
+ * @Description:
+ */
+public interface DeviceVideoMapper extends BaseMapper {
+ /**
+ * 条件查询视频设备列表
+ * @param status 是否在线
+ * @param keyword 设备名称或者编码
+ * @return {@link List< DeviceVideoListResp>}
+ */
+ List selectDeviceVideoList(@Param("status") String status, @Param("keyword") String keyword, @Param("hostAddress") String hostAddress);
+
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/mapper/IpConfigMapper.java b/sip/src/main/java/com/dite/znpt/monitor/mapper/IpConfigMapper.java
new file mode 100644
index 0000000..1332af0
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/mapper/IpConfigMapper.java
@@ -0,0 +1,13 @@
+package com.dite.znpt.monitor.mapper;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.dite.znpt.monitor.domain.entity.IpConfigEntity;
+
+/**
+ * @Date: 2023/09/05 16:39
+ * @Description: 监控设备IP配置表数据库访问层
+ */
+public interface IpConfigMapper extends BaseMapper {
+}
+
diff --git a/sip/src/main/java/com/dite/znpt/monitor/mapper/StreamMediaFormatMapper.java b/sip/src/main/java/com/dite/znpt/monitor/mapper/StreamMediaFormatMapper.java
new file mode 100644
index 0000000..a3ce77a
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/mapper/StreamMediaFormatMapper.java
@@ -0,0 +1,12 @@
+package com.dite.znpt.monitor.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.dite.znpt.monitor.domain.vo.video.StreamMediaFormat;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/11 15:00
+ * @Description:
+ */
+public interface StreamMediaFormatMapper extends BaseMapper {
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/ZlmApi.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/ZlmApi.java
new file mode 100644
index 0000000..f8604da
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/ZlmApi.java
@@ -0,0 +1 @@
+package com.dite.znpt.monitor.media.zlm;
import com.dite.znpt.monitor.media.zlm.dto.ServerConfig;
import com.dite.znpt.monitor.media.zlm.dto.ServerInfo;
import com.dite.znpt.monitor.media.zlm.dto.req.*;
import com.dite.znpt.monitor.media.zlm.dto.resp.*;
import java.io.IOException;
import java.util.List;
/**
* @Author: huise23
* @Date: 2022/8/29 10:14
* @Description: Zlm客户端启动类
*/
public interface ZlmApi {
/**
* 获取API列表
* api: /index/api/getApiList
*
* @return Api列表
*/
List getApiList(ServerInfo server);
/**
* 获取各epoll(或select)线程负载以及延时
* api: /index/api/getThreadsLoad
*
* @return 各epoll(或select)线程负载以及延时
*/
List getThreadsLoad(ServerInfo server);
/**
* 获取各后台epoll(或select)线程负载以及延时
* api: /index/api/getWorkThreadsLoad
*
* @return 各后台epoll(或select)线程负载以及延时
*/
List getWorkThreadsLoad(ServerInfo server);
/**
* 获取服务器配置
* api: /index/api/getServerConfig
*
* @return 服务器配置
*/
List getServerConfig(ServerInfo server);
/**
* 设置服务器配置
* api: /index/api/setServerConfig
*
* @param config 服务器配置
* @return 操作结果
*/
Integer setServerConfig(ServerInfo server, ServerConfig config);
/**
* 重启服务器,只有Daemon方式才能重启,否则是直接关闭!
* api: /index/api/restartServer
*
* @return 操作结果
*/
Boolean restartServer(ServerInfo server);
/**
* 获取流列表,可选筛选参数
* api: /index/api/getMediaList
*
* @param req 请求参数
* @return 操作结果
*/
List getMediaList(ServerInfo server, StreamReq req);
/**
* 关闭流(目前所有类型的流都支持关闭)
* api: /index/api/close_streams
*
* @param req 请求参数
* @return 操作结果
*/
CloseStreamResp closeStreams(ServerInfo server, CloseStreamReq req);
/**
* 获取所有TcpSession列表(获取所有tcp客户端相关信息)
* api: /index/api/getAllSession
*
* @param req 请求参数
* @return 所有TcpSession列表
*/
List getAllSession(ServerInfo server, GetAllSessionReq req);
/**
* 断开tcp连接,比如说可以断开rtsp、rtmp播放器等
* api: /index/api/kick_session
*
* @param id 客户端唯一id,可以通过getAllSession接口获取
* @return 操作结果
*/
Boolean kickSession(ServerInfo server, Long id);
/**
* 断开tcp连接,比如说可以断开rtsp、rtmp播放器等
* api: /index/api/kick_sessions
*
* @param req 请求参数
* @return 操作结果
*/
Integer kickSession(ServerInfo server, GetAllSessionReq req);
/**
* 动态添加rtsp/rtmp/hls拉流代理(只支持H264/H265/aac/G711负载)
* api: /index/api/addStreamProxy
*
* @param req 请求参数
* @return 唯一Key
*/
String addStreamProxy(ServerInfo server, StreamProxyReq req);
/**
* 关闭拉流代理
* api: /index/api/delStreamProxy
*
* @param key addStreamProxy接口返回的key
* @return 操作结果
*/
Boolean delStreamProxy(ServerInfo server, String key);
/**
* 通过fork FFmpeg进程的方式拉流代理,支持任意协议
* api: /index/api/addFFmpegSource
*
* @param req 请求参数
* @return 唯一Key
*/
String addFfMpegSource(ServerInfo server, FFmpegSourceReq req);
/**
* 关闭ffmpeg拉流代理
* api: /index/api/delFFmpegSource
*
* @param key addFFmpegSource接口返回的key
* @return 操作结果
*/
Boolean delFfMpegSource(ServerInfo server, String key);
/**
* 获取rtp代理时的某路ssrc rtp信息
* api: /index/api/getRtpInfo
*
* @param streamId RTP的ssrc,16进制字符串或者是流的id(openRtpServer接口指定)
* @return 操作结果
*/
RtpInfoResp getRtpInfo(ServerInfo server, String streamId);
/**
* 搜索文件系统,获取流对应的录像文件列表或日期文件夹列表
* api: /index/api/getMp4RecordFile
*
* @param req 请求参数
* @return 操作结果
*/
Mp4RecordFileResp getMp4RecordFile(ServerInfo server, GetMp4RecordFileReq req);
/**
* 开始录制hls或MP4
* api: /index/api/startRecord
*
* @param req 请求参数
* @return 操作结果
*/
Boolean startRecord(ServerInfo server, RecordReq req);
/**
* 停止录制流
* api: /index/api/stopRecord
*
* @param req 请求参数
* @return 操作结果
*/
Boolean stopRecord(ServerInfo server, RecordReq req);
/**
* 获取流录制状态
* api: /index/api/isRecording
*
* @param req 请求参数
* @return 操作结果
*/
Boolean isRecording(ServerInfo server, RecordReq req);
/**
* 获取截图或生成实时截图并返回
* api: /index/api/getSnap
*
* @param req 请求参数
* @return jpeg格式的图片,可以在浏览器直接打开
*/
void getSnap(ServerInfo server, SnapReq req) throws IOException;
/**
* 创建GB28181 RTP接收端口,如果该端口接收数据超时,则会自动被回收(不用调用closeRtpServer接口)
* api: /index/api/openRtpServer
*
* @param req 请求参数
* @return 接收端口,方便获取随机端口号
*/
Integer openRtpServer(ServerInfo server, RtpServerReq req);
/**
* 关闭GB28181 RTP接收端口
* api: /index/api/closeRtpServer
*
* @param streamId 该端口绑定的流ID,该端口只能创建这一个流(而不是根据ssrc创建多个)
* @return 是否找到记录并关闭
*/
Boolean closeRtpServer(ServerInfo server, String streamId);
/**
* 获取openRtpServer接口创建的所有RTP服务器
* api: /index/api/listRtpServer
*
* @return 是否找到记录并关闭
*/
List listRtpServer(ServerInfo server);
/**
* 作为GB28181客户端,启动ps-rtp推流,支持rtp/udp方式;
* 该接口支持rtsp/rtmp等协议转ps-rtp推流。第一次推流失败会直接返回错误,成功一次后,后续失败也将无限重试。
* api: /index/api/startSendRtp
*
* @param req 请求参数
* @return 使用的本地端口号
*/
Integer startSendRtp(ServerInfo server, SendRtpReq req);
/**
* 作为GB28181 Passive TCP服务器;
* 该接口支持rtsp/rtmp等协议转ps-rtp被动推流。
* 调用该接口,zlm会启动tcp服务器等待连接请求,
* 连接建立后,zlm会关闭tcp服务器,然后源源不断的往客户端推流。
* 第一次推流失败会直接返回错误,成功一次后,后续失败也将无限重试(不停地建立tcp监听,超时后再关闭)。
* api: /index/api/startSendRtpPassive
*
* @param req 请求参数
* @return 使用的本地端口号
*/
Integer startSendRtpPassive(ServerInfo server, SendRtpReq req);
/**
* 停止GB28181 ps-rtp推流
* api: /index/api/stopSendRtp
*
* @param req 请求参数
* @return 操作结果
*/
Boolean stopSendRtp(ServerInfo server, SendRtpReq req);
/**
* 获取主要对象个数统计,主要用于分析内存性能
* api: /index/api/getStatistic
*
* @return 操作结果
*/
StatisticResp getStatistic(ServerInfo server);
/**
* 添加rtsp/rtmp主动推流(把本服务器的直播流推送到其他服务器去)
* api: /index/api/addStreamPusherProxy
*
* @param req 请求参数
* @return 流的唯一标识
*/
String addStreamPusherProxy(ServerInfo server, StreamPusherProxyReq req);
/**
* 关闭推流
* api: /index/api/delStreamPusherProxy
*
* @param key 流的唯一标识
* @return 操作结果
*/
Boolean delStreamPusherProxy(ServerInfo server, String key);
}
\ No newline at end of file
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/ZlmHook.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/ZlmHook.java
new file mode 100644
index 0000000..a9c1b11
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/ZlmHook.java
@@ -0,0 +1,135 @@
+package com.dite.znpt.monitor.media.zlm;
+
+import com.dite.znpt.monitor.media.zlm.dto.ServerConfig;
+import com.dite.znpt.monitor.media.zlm.dto.event.*;
+import com.dite.znpt.monitor.media.zlm.impl.ZlmHookService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/29 10:22
+ * @Description:
+ */
+@Slf4j
+@RestController
+@RequestMapping("/index/hook")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class ZlmHook {
+ private final ZlmHookService service;
+
+ /**
+ * 流量统计事件,播放器或推流器断开时并且耗用流量超过特定阈值时会触发此事件,
+ * 阈值通过配置文件general.flowThreshold配置;此事件对回复不敏感。
+ */
+ @PostMapping(value = "/on_flow_report")
+ public BaseEventResp onFlowReport(@RequestBody FlowReportReq req) {
+ return service.onFlowReport(req);
+ }
+
+ /**
+ * 访问http文件服务器上hls之外的文件时触发。
+ */
+ @PostMapping(value = "/on_http_access")
+ public HttpAccessResp onHttpAccess(@RequestBody HttpAccessReq req) {
+ return service.onHttpAccess(req);
+ }
+
+ /**
+ * 播放器鉴权事件,rtsp/rtmp/http-flv/ws-flv/hls的播放都将触发此鉴权事件;
+ * 如果流不存在,那么先触发on_play事件然后触发on_stream_not_found事件。
+ * 播放rtsp流时,如果该流启动了rtsp专属鉴权(on_rtsp_realm)那么将不再触发on_play事件。
+ */
+ @PostMapping(value = "/on_play")
+ public BaseEventResp onPlay(@RequestBody PlayReq req) {
+ return service.onPlay(req);
+ }
+
+ /**
+ * rtsp/rtmp/rtp推流鉴权事件。
+ */
+ @PostMapping(value = "/on_publish")
+ public PublishResp onPublish(@RequestBody PublishReq req) {
+ return service.onPublish(req);
+ }
+
+
+ /**
+ * 录制mp4完成后通知事件;此事件对回复不敏感。
+ */
+ @PostMapping(value = "/on_record_mp4")
+ public BaseEventResp onRecordMp4(@RequestBody RecordMp4Req req) {
+ return service.onRecordMp4(req);
+ }
+
+ /**
+ * 该rtsp流是否开启rtsp专用方式的鉴权事件,开启后才会触发on_rtsp_auth事件。
+ * 需要指出的是rtsp也支持url参数鉴权,它支持两种方式鉴权。
+ */
+ @PostMapping(value = "/on_rtsp_realm")
+ public BaseEventResp onRtspRealm(@RequestBody RtspRealmReq req) {
+ return service.onRtspRealm(req);
+ }
+
+ /**
+ * rtsp专用的鉴权事件,先触发on_rtsp_realm事件然后才会触发on_rtsp_auth事件。
+ */
+ @PostMapping(value = "/on_rtsp_auth")
+ public RtspAuthResp onRtspAuth(@RequestBody RtspAuthReq req) {
+ return service.onRtspAuth(req);
+ }
+
+ /**
+ * shell登录鉴权,ZLMediaKit提供简单的telnet调试方式
+ * 使用telnet 127.0.0.1 9000能进入MediaServer进程的shell界面。
+ */
+ @PostMapping(value = "/on_shell_login")
+ public BaseEventResp onShellLogin(@RequestBody ShellLoginReq req) {
+ return service.onShellLogin(req);
+ }
+
+ /**
+ * rtsp/rtmp流注册或注销时触发此事件;此事件对回复不敏感。
+ */
+ @PostMapping(value = "/on_stream_changed")
+ public BaseEventResp onStreamChanged(@RequestBody StreamChangedReq req) {
+ return service.onStreamChanged(req);
+ }
+
+ /**
+ * 流无人观看时事件,用户可以通过此事件选择是否关闭无人看的流。
+ */
+ @PostMapping(value = "/on_stream_none_reader")
+ public BaseEventResp onStreamNoneReader(@RequestBody StreamNoneReaderReq req) {
+ return service.onStreamNoneReader(req);
+ }
+
+ /**
+ * 流未找到事件,用户可以在此事件触发时,立即去拉流,这样可以实现按需拉流;此事件对回复不敏感。
+ */
+ @PostMapping(value = "/on_stream_not_found")
+ public BaseEventResp onStreamNotFound(@RequestBody StreamNotFoundReq req) {
+ return service.onStreamNotFound(req);
+ }
+
+ /**
+ * 服务器启动事件,可以用于监听服务器崩溃重启;此事件对回复不敏感。
+ */
+ @PostMapping(value = "/on_server_started")
+ public BaseEventResp onServerStarted(@RequestBody ServerConfig req) {
+ return service.onServerStarted(req);
+ }
+
+ /**
+ * 服务器定时上报时间,上报间隔可配置,默认10s上报一次
+ */
+ @PostMapping(value = "/on_server_keepalive")
+ public BaseEventResp onServerKeepalive(@RequestBody ServerKeepaliveReq req) {
+ return service.onServerKeepalive(req);
+ }
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/ZlmService.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/ZlmService.java
new file mode 100644
index 0000000..b56e1e1
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/ZlmService.java
@@ -0,0 +1,42 @@
+package com.dite.znpt.monitor.media.zlm;
+
+import com.dite.znpt.monitor.media.zlm.dto.MediaItem;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/30 10:39
+ * @Description: 流媒体服务管理主业务
+ */
+public interface ZlmService {
+ /**
+ * 点播视频
+ *
+ * @param deviceCode 设备编码
+ * @param channelCode 通道编码
+ * @return 流信息
+ */
+ MediaItem play(String deviceCode, String channelCode);
+
+ /**
+ * 失败的时候释放流媒体资源
+ *
+ * @param deviceCode 设备编码
+ * @param channelCode 通道编码
+ */
+ void release(String deviceCode, String channelCode);
+
+ /**
+ * 失败的时候释放流媒体资源
+ *
+ * @param media 流媒体信息
+ */
+ void release(MediaItem media);
+
+ /**
+ * 停止点播
+ *
+ * @param mediaServerId 流媒体服务器id,通过配置文件设置
+ * @param streamId 流ID
+ */
+ void display(String mediaServerId, String streamId);
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/cache/MediaServerCache.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/cache/MediaServerCache.java
new file mode 100644
index 0000000..4f13dad
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/cache/MediaServerCache.java
@@ -0,0 +1,38 @@
+package com.dite.znpt.monitor.media.zlm.cache;
+
+import com.dite.znpt.monitor.media.zlm.dto.ServerItem;
+import com.dite.znpt.service.impl.RedisService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/30 15:46
+ * @Description:
+ */
+@Component
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class MediaServerCache {
+ private final RedisService redisService;
+ private final String zlm_key = "zlm_media_server";
+
+
+ public void putLoad(ServerItem serverItem) {
+ redisService.setCacheObject(zlm_key, serverItem);
+ }
+
+ /**
+ * 获取zlm节点
+ */
+ public ServerItem getLoad() {
+ return redisService.getCacheObject(zlm_key);
+ }
+
+ public void releaseSsrc(String ssrc) {
+ ServerItem item = getLoad();
+ item.releaseSsrc(ssrc);
+ putLoad(item);
+ }
+
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/cache/MediaServerChannelCache.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/cache/MediaServerChannelCache.java
new file mode 100644
index 0000000..27b7fbb
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/cache/MediaServerChannelCache.java
@@ -0,0 +1,54 @@
+package com.dite.znpt.monitor.media.zlm.cache;
+
+import cn.hutool.core.util.StrUtil;
+import com.dite.znpt.monitor.media.zlm.dto.MediaItem;
+import com.dite.znpt.service.impl.RedisService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/30 15:46
+ * @Description:
+ */
+@Component
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class MediaServerChannelCache {
+ private final RedisService redisService;
+
+ private String getKey(String deviceCode, String channelCode) {
+ return StrUtil.format("zlm_media_server_channel:{}:{}", deviceCode, channelCode);
+ }
+
+ private String getStreamKey(String mediaServerId, String streamId) {
+ return StrUtil.format("zlm_media_server_channel_stream_key:{}:{}", mediaServerId, streamId);
+ }
+
+ public boolean has(String deviceCode, String channelCode) {
+ return redisService.hasKey(getKey(deviceCode, channelCode));
+ }
+
+ public MediaItem get(String deviceCode, String channelCode) {
+ return redisService.getCacheObject(getKey(deviceCode, channelCode));
+ }
+
+ public void put(String deviceCode, String channelCode, MediaItem media) {
+ String key = getKey(deviceCode, channelCode);
+ redisService.setCacheObject(key, media);
+ redisService.setCacheObject(getStreamKey(media.getConfig().getGeneralMediaServerId(), media.getStreamId()), key);
+ }
+
+ public void delete(MediaItem media) {
+ redisService.deleteObject(getKey(media.getDeviceCode(), media.getChannelCode()));
+ redisService.deleteObject(getStreamKey(media.getConfig().getGeneralMediaServerId(), media.getStreamId()));
+ }
+
+ public MediaItem getByStream(String mediaServerId, String streamId) {
+ String key = redisService.getCacheObject(getStreamKey(mediaServerId, streamId));
+ if (StrUtil.isNotBlank(key)) {
+ return redisService.getCacheObject(key);
+ }
+ return null;
+ }
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/config/StreamMediaServerConfig.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/config/StreamMediaServerConfig.java
new file mode 100644
index 0000000..e2a7d07
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/config/StreamMediaServerConfig.java
@@ -0,0 +1,46 @@
+package com.dite.znpt.monitor.media.zlm.config;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+@Data
+@Configuration
+@ConfigurationProperties(prefix = "zlm-config")
+public class StreamMediaServerConfig {
+
+ @ApiModelProperty(value = "'流媒体名称'")
+ private String mediaName;
+
+ @ApiModelProperty(value = "流媒体服务商")
+ private String mediaService;
+
+ @ApiModelProperty(value = "公网ip")
+ private String publicHost;
+
+ @ApiModelProperty(value = "接口ip")
+ private String apiHost;
+
+ @ApiModelProperty(value = "接口端口")
+ private Integer apiPort;
+
+ @ApiModelProperty(value = "密钥")
+ private String secretKey;
+
+ @ApiModelProperty(value = "流id前缀")
+ private String streamPrefix;
+
+ @ApiModelProperty(value = "rtp ip")
+ private String rtpHost;
+
+ @ApiModelProperty(value = "rtp 端口")
+ private Integer rtpPort;
+
+ @ApiModelProperty(value = "动态端口起始值")
+ private String dynamicPortStart;
+
+ @ApiModelProperty(value = "动态端口结束值")
+ private String dynamicPortEnd;
+
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/MediaItem.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/MediaItem.java
new file mode 100644
index 0000000..a39c8c4
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/MediaItem.java
@@ -0,0 +1,130 @@
+package com.dite.znpt.monitor.media.zlm.dto;
+
+import cn.hutool.core.util.StrUtil;
+import com.dite.znpt.monitor.domain.vo.video.StreamMediaFormat;
+import com.dite.znpt.monitor.media.zlm.dto.resp.RtpInfoResp;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/29 15:41
+ * @Description:
+ */
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+public class MediaItem implements Serializable {
+ private static final long serialVersionUID = -6679610697837602559L;
+ /**
+ * 设备编码
+ */
+ private String deviceCode;
+ /**
+ * 通道编码
+ */
+ private String channelCode;
+ /**
+ * 节点信息ID
+ */
+ private String configId;
+ /**
+ * 节点信息ID
+ */
+ private ServerInfo server;
+ /**
+ * 节点格式信息
+ */
+ private List formatList;
+ /**
+ * 节点配置信息
+ */
+ private ServerConfig config;
+ /**
+ * 流ID
+ */
+ private String streamId;
+ /**
+ * 播放流信息
+ */
+ private RtpInfoResp rtp;
+ /**
+ * Rtp服务监听端口
+ */
+ private Integer rtpPort;
+ /**
+ * SSRC源地址
+ */
+ private String ssrc;
+ /**
+ * rtmp播放地址
+ */
+ private String rtmpUrl;
+ /**
+ * rtmpSsl播放地址
+ */
+ private String rtmpSslUrl;
+ /**
+ * rtsp播放地址
+ */
+ private String rtspUrl;
+ /**
+ * rtspSsl播放地址
+ */
+ private String rtspSslUrl;
+
+ /**
+ * rtc流地址
+ */
+ private String rtc;
+
+ /**
+ * rtcs流地址
+ */
+ private String rtcs;
+
+ /**
+ * 是否缓存
+ */
+ private Boolean isCache;
+
+ public List getFormatList(String mediaRouter) {
+ if (StrUtil.isNotBlank(streamId)) {
+ formatList.forEach(item -> item.generateUrl(server.getApiHost(), streamId, config, mediaRouter));
+ }
+ return formatList;
+ }
+
+ public String getRtmpUrl() {
+ if (StrUtil.isBlank(streamId)) {
+ return "";
+ }
+ return StrUtil.format("rtmp://{}:{}/rtp/{}", server.getApiHost(), config.getRtmpPort(), streamId);
+ }
+
+ public String getRtmpSslUrl() {
+ if (StrUtil.isBlank(streamId)) {
+ return "";
+ }
+ return config.getRtspSslPort() > 0 ? StrUtil.format("rtmps://{}:{}/rtp/{}", server.getApiHost(), config.getRtspSslPort(), streamId) : "";
+ }
+
+
+ public String getRtspUrl() {
+ if (StrUtil.isBlank(streamId)) {
+ return "";
+ }
+ return StrUtil.format("rtsp://{}:{}/rtp/{}", server.getApiHost(), config.getRtspPort(), streamId);
+ }
+
+ public String getRtspSslUrl() {
+ if (StrUtil.isBlank(streamId)) {
+ return "";
+ }
+ return config.getRtspSslPort() > 0 ? StrUtil.format("rtsps://{}:{}/rtp/{}", server.getApiHost(), config.getRtspSslPort(), streamId) : "";
+ }
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/ServerConfig.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/ServerConfig.java
new file mode 100644
index 0000000..62b51d7
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/ServerConfig.java
@@ -0,0 +1,852 @@
+package com.dite.znpt.monitor.media.zlm.dto;
+
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.annotation.JSONField;
+import com.dite.znpt.monitor.media.zlm.config.StreamMediaServerConfig;
+import com.dite.znpt.monitor.media.zlm.dto.req.BaseReq;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/29 10:54
+ * @Description: 服务器配置
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@Accessors(chain = true)
+public class ServerConfig extends BaseReq {
+ // ----------------------------------------------- api -----------------------------------------------
+ /**
+ * 是否调试http api,启用调试后,会打印每次http请求的内容和回复
+ * apiDebug=1
+ */
+ @JSONField(name = "api.apiDebug")
+ private Integer apiDebug;
+ /**
+ * 一些比较敏感的http api在访问时需要提供secret,否则无权限调用
+ * 如果是通过127.0.0.1访问,那么可以不提供secret
+ * secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc
+ */
+ @JSONField(name = "api.secret")
+ private String apiSecret;
+ /**
+ * 截图保存路径根目录,截图通过http api(/index/api/getSnap)生成和获取
+ * snapRoot=./www/snap/
+ */
+ @JSONField(name = "api.snapRoot")
+ private String apiSnapRoot;
+ /**
+ * 默认截图图片,在启动FFmpeg截图后但是截图还未生成时,可以返回默认的预设图片
+ * defaultSnap=./www/logo.png
+ */
+ @JSONField(name = "api.defaultSnap")
+ private String apiDefaultSnap;
+ // ----------------------------------------------- ffmpeg -----------------------------------------------
+ /**
+ * FFmpeg可执行程序路径,支持相对路径/绝对路径
+ * bin=/usr/bin/ffmpeg
+ */
+ @JSONField(name = "ffmpeg.bin")
+ private String ffmpegBin;
+ /**
+ * FFmpeg拉流再推流的命令模板,通过该模板可以设置再编码的一些参数
+ * cmd=%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s
+ */
+ @JSONField(name = "ffmpeg.cmd")
+ private String ffmpegCmd;
+ /**
+ * FFmpeg生成截图的命令,可以通过修改该配置改变截图分辨率或质量
+ * snap=%s -i %s -y -f mjpeg -t 0.001 %s
+ */
+ @JSONField(name = "ffmpeg.snap")
+ private String ffmpegSnap;
+ /**
+ * FFmpeg日志的路径,如果置空则不生成FFmpeg日志
+ * 可以为相对(相对于本可执行程序目录)或绝对路径
+ * log=./ffmpeg/ffmpeg.log
+ */
+ @JSONField(name = "ffmpeg.log")
+ private String ffmpegLog;
+ /**
+ * 自动重启的时间(秒), 默认为0, 也就是不自动重启. 主要是为了避免长时间ffmpeg拉流导致的不同步现象
+ * restart_sec=0
+ */
+ @JSONField(name = "ffmpeg.restart_sec")
+ private String ffmpegRestartSec;
+ // ----------------------------------------------- general -----------------------------------------------
+ /**
+ * 是否启用虚拟主机
+ * enableVhost=0
+ */
+ @JSONField(name = "general.enableVhost")
+ private Integer enableVhost;
+ /**
+ * 播放器或推流器在断开后会触发hook.on_flow_report事件(使用多少流量事件),
+ * flowThreshold参数控制触发hook.on_flow_report事件阈值,使用流量超过该阈值后才触发,单位KB
+ * flowThreshold=1024
+ */
+ @JSONField(name = "general.flowThreshold")
+ private Integer generalFlowThreshold;
+ /**
+ * 播放最多等待时间,单位毫秒
+ * 播放在播放某个流时,如果该流不存在,
+ * ZLMediaKit会最多让播放器等待maxStreamWaitMS毫秒
+ * 如果在这个时间内,该流注册成功,那么会立即返回播放器播放成功
+ * 否则返回播放器未找到该流,该机制的目的是可以先播放再推流
+ * maxStreamWaitMS=15000
+ */
+ @JSONField(name = "general.maxStreamWaitMS")
+ private Integer generalMaxStreamWaitMs;
+ /**
+ * 某个流无人观看时,触发hook.on_stream_none_reader事件的最大等待时间,单位毫秒
+ * 在配合hook.on_stream_none_reader事件时,可以做到无人观看自动停止拉流或停止接收推流
+ * streamNoneReaderDelayMS=20000
+ */
+ @JSONField(name = "general.streamNoneReaderDelayMS")
+ private Integer generalStreamNoneReaderDelayMs;
+ /**
+ * 是否全局添加静音aac音频,转协议时有效
+ * 有些播放器在打开单视频流时不能秒开,添加静音音频可以加快秒开速度
+ * addMuteAudio=1
+ */
+ @JSONField(name = "general.addMuteAudio")
+ private Integer generalAddMuteAudio;
+ /**
+ * 拉流代理时如果断流再重连成功是否删除前一次的媒体流数据,如果删除将重新开始,
+ * 如果不删除将会接着上一次的数据继续写(录制hls/mp4时会继续在前一个文件后面写)
+ * resetWhenRePlay=1
+ */
+ @JSONField(name = "general.resetWhenRePlay")
+ private Integer generalResetWhenRePlay;
+ /**
+ * 是否默认推流时转换成hls,hook接口(on_publish)中可以覆盖该设置
+ * publishToHls=1
+ */
+ @JSONField(name = "general.publishToHls")
+ private Integer generalPublishToHls;
+ /**
+ * 是否默认推流时mp4录像,hook接口(on_publish)中可以覆盖该设置
+ * publishToMP4=0
+ */
+ @JSONField(name = "general.publishToMP4")
+ private Integer generalPublishToMP4;
+ /**
+ * 合并写缓存大小(单位毫秒),合并写指服务器缓存一定的数据后才会一次性写入socket,这样能提高性能,但是会提高延时
+ * 开启后会同时关闭TCP_NODELAY并开启MSG_MORE
+ * mergeWriteMS=0
+ */
+ @JSONField(name = "general.mergeWriteMS")
+ private Integer generalMergeWriteMS;
+ /**
+ * 全局的时间戳覆盖开关,在转协议时,对frame进行时间戳覆盖
+ * 该开关对rtsp/rtmp/rtp推流、rtsp/rtmp/hls拉流代理转协议时生效
+ * 会直接影响rtsp/rtmp/hls/mp4/flv等协议的时间戳
+ * 同协议情况下不影响(例如rtsp/rtmp推流,那么播放rtsp/rtmp时不会影响时间戳)
+ * modifyStamp=0
+ */
+ @JSONField(name = "general.modifyStamp")
+ private Integer generalModifyStamp;
+ /**
+ * 服务器唯一id,用于触发hook时区别是哪台服务器
+ * mediaServerId=your_server_id
+ */
+ @JSONField(name = "general.mediaServerId")
+ private String generalMediaServerId;
+ /**
+ * 转协议是否全局开启或关闭音频
+ * enable_audio=1
+ */
+ @JSONField(name = "general.enable_audio")
+ private Integer generalEnableAudio;
+ // ###### 以下是按需转协议的开关,在测试ZLMediaKit的接收推流性能时,请把下面开关置1
+ // ###### 如果某种协议你用不到,你可以把以下开关置1以便节省资源(但是还是可以播放,只是第一个播放者体验稍微差点),
+ // ###### 如果某种协议你想获取最好的用户体验,请置0(第一个播放者可以秒开,且不花屏)
+ /**
+ * hls协议是否按需生成,如果hls.segNum配置为0(意味着hls录制),那么hls将一直生成(不管此开关)
+ * hls_demand=0
+ */
+ @JSONField(name = "general.hls_demand")
+ private Integer generalHlsDemand;
+ /**
+ * rtsp[s]协议是否按需生成
+ * rtsp_demand=0
+ */
+ @JSONField(name = "general.rtsp_demand")
+ private Integer generalRtspDemand;
+ /**
+ * rtmp[s]、http[s]-flv、ws[s]-flv协议是否按需生成
+ * rtmp_demand=0
+ */
+ @JSONField(name = "general.rtmp_demand")
+ private Integer generalRtmpDemand;
+ /**
+ * http[s]-ts协议是否按需生成
+ * ts_demand=0
+ */
+ @JSONField(name = "general.ts_demand")
+ private Integer generalTsDemand;
+ /**
+ * http[s]-fmp4、ws[s]-fmp4协议是否按需生成
+ * fmp4_demand=0
+ */
+ @JSONField(name = "general.fmp4_demand")
+ private Integer generalFmp4Demand;
+ /**
+ * 最多等待未初始化的Track时间,单位毫秒,超时之后会忽略未初始化的Track
+ * wait_track_ready_ms=10000
+ */
+ @JSONField(name = "general.wait_track_ready_ms")
+ private Integer generalWaitTrackReadyMs;
+ /**
+ * 如果流只有单Track,最多等待若干毫秒,超时后未收到其他Track的数据,则认为是单Track
+ * 如果协议元数据有声明特定track数,那么无此等待时间
+ * wait_add_track_ms=3000
+ */
+ @JSONField(name = "general.wait_add_track_ms")
+ private Integer generalWaitAddTrackMs;
+ /**
+ * 如果track未就绪,我们先缓存帧数据,但是有最大个数限制,防止内存溢出
+ * unready_frame_cache=100
+ */
+ @JSONField(name = "general.unready_frame_cache")
+ private Integer generalUnreadyFrameCache;
+ /**
+ * 推流断开后可以在超时时间内重新连接上继续推流,这样播放器会接着播放。
+ * 置0关闭此特性(推流断开会导致立即断开播放器)
+ * 此参数不应大于播放器超时时间
+ * continue_push_ms=15000
+ */
+ @JSONField(name = "general.continue_push_ms")
+ private Integer generalContinuePushMs;
+ // ----------------------------------------------- hls -----------------------------------------------
+ /**
+ * hls写文件的buf大小,调整参数可以提高文件io性能
+ * fileBufSize=65536
+ */
+ @JSONField(name = "hls.fileBufSize")
+ private Integer hlsFileBufSize;
+ /**
+ * hls保存文件路径
+ * 可以为相对(相对于本可执行程序目录)或绝对路径
+ * filePath=./www
+ */
+ @JSONField(name = "hls.filePath")
+ private String hlsFilePath;
+ /**
+ * hls最大切片时间
+ * segDur=2
+ */
+ @JSONField(name = "hls.segDur")
+ private Integer hlsSegDur;
+ /**
+ * m3u8索引中,hls保留切片个数(实际保留切片个数大2~3个)
+ * 如果设置为0,则不删除切片,而是保存为点播
+ * segNum=3
+ */
+ @JSONField(name = "hls.segNum")
+ private Integer hlsSegNum;
+ /**
+ * HLS切片从m3u8文件中移除后,继续保留在磁盘上的个数
+ * segRetain=5
+ */
+ @JSONField(name = "hls.segRetain")
+ private Integer hlsSegRetain;
+ /**
+ * 是否广播 ts 切片完成通知
+ * broadcastRecordTs=0
+ */
+ @JSONField(name = "hls.broadcastRecordTs")
+ private Integer hlsBroadcastRecordTs;
+ /**
+ * 直播hls文件删除延时,单位秒,issue: #913
+ * deleteDelaySec=0
+ */
+ @JSONField(name = "hls.deleteDelaySec")
+ private Integer hlsDeleteDelaySec;
+ /**
+ * 是否保留hls文件,此功能部分等效于segNum=0的情况
+ * 不同的是这个保留不会在m3u8文件中体现
+ * 0为不保留,不起作用
+ * 1为保留,则不删除hls文件,如果开启此功能,注意磁盘大小,或者定期手动清理hls文件
+ * segKeep=0
+ */
+ @JSONField(name = "hls.segKeep")
+ private Integer hlsSegKeep;
+ // ----------------------------------------------- hook -----------------------------------------------
+ /**
+ * 在推流时,如果url参数匹对admin_params,那么可以不经过hook鉴权直接推流成功,播放时亦然
+ * 该配置项的目的是为了开发者自己调试测试,该参数暴露后会有泄露隐私的安全隐患
+ * admin_params=secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc
+ */
+ @JSONField(name = "hook.admin_params")
+ private String hookAdminParams;
+ /**
+ * 是否启用hook事件,启用后,推拉流都将进行鉴权
+ * enable=0
+ */
+ @JSONField(name = "hook.enable")
+ private Integer hookHookEnable;
+ /**
+ * 播放器或推流器使用流量事件,置空则关闭
+ * on_flow_report=https://127.0.0.1/index/hook/on_flow_report
+ */
+ @JSONField(name = "hook.on_flow_report")
+ private String hookOnFlowReport;
+ /**
+ * 访问http文件鉴权事件,置空则关闭鉴权
+ * on_http_access=https://127.0.0.1/index/hook/on_http_access
+ */
+ @JSONField(name = "hook.on_http_access")
+ private String hookOnHttpAccess;
+ /**
+ * 播放鉴权事件,置空则关闭鉴权
+ * on_play=https://127.0.0.1/index/hook/on_play
+ */
+ @JSONField(name = "hook.on_play")
+ private String hookOnPlay;
+ /**
+ * 推流鉴权事件,置空则关闭鉴权
+ * on_publish=https://127.0.0.1/index/hook/on_publish
+ */
+ @JSONField(name = "hook.on_publish")
+ private String hookOnPublish;
+ /**
+ * 录制mp4切片完成事件
+ * on_record_mp4=https://127.0.0.1/index/hook/on_record_mp4
+ */
+ @JSONField(name = "hook.on_record_mp4")
+ private String hookOnRecordMp4;
+ /**
+ * 录制 hls ts 切片完成事件
+ * on_record_ts=https://127.0.0.1/index/hook/on_record_ts
+ */
+ @JSONField(name = "hook.on_record_ts")
+ private String hookOnRecordTs;
+ /**
+ * rtsp播放鉴权事件,此事件中比对rtsp的用户名密码
+ * on_rtsp_auth=https://127.0.0.1/index/hook/on_rtsp_auth
+ */
+ @JSONField(name = "hook.on_rtsp_auth")
+ private String hookOnRtspAuth;
+ /**
+ * rtsp播放是否开启专属鉴权事件,置空则关闭rtsp鉴权。rtsp播放鉴权还支持url方式鉴权
+ * 建议开发者统一采用url参数方式鉴权,rtsp用户名密码鉴权一般在设备上用的比较多
+ * 开启rtsp专属鉴权后,将不再触发on_play鉴权事件
+ * on_rtsp_realm=https://127.0.0.1/index/hook/on_rtsp_realm
+ */
+ @JSONField(name = "hook.on_rtsp_realm")
+ private String hookOnRtspRealm;
+ /**
+ * 远程telnet调试鉴权事件
+ * on_shell_login=https://127.0.0.1/index/hook/on_shell_login
+ */
+ @JSONField(name = "hook.on_shell_login")
+ private String hookOnShellLogin;
+ /**
+ * 直播流注册或注销事件
+ * on_stream_changed=https://127.0.0.1/index/hook/on_stream_changed
+ */
+ @JSONField(name = "hook.on_stream_changed")
+ private String hookOnStreamChanged;
+ /**
+ * 服务器启动报告,可以用于服务器的崩溃重启事件监听
+ * on_server_started=https://127.0.0.1/index/hook/on_server_started
+ */
+ @JSONField(name = "hook.on_server_started")
+ private String hookOnServerStarted;
+ /**
+ * server保活上报
+ * on_server_keepalive=https://127.0.0.1/index/hook/on_server_keepalive
+ */
+ @JSONField(name = "hook.on_server_keepalive")
+ private String hookOnServerKeepalive;
+ /**
+ * 无人观看流事件,通过该事件,可以选择是否关闭无人观看的流。配合general.streamNoneReaderDelayMS选项一起使用
+ * on_stream_none_reader=https://127.0.0.1/index/hook/on_stream_none_reader
+ */
+ @JSONField(name = "hook.on_stream_none_reader")
+ private String hookOnStreamNoneReader;
+ /**
+ * 播放时,未找到流事件,通过配合hook.on_stream_none_reader事件可以完成按需拉流
+ * on_stream_not_found=https://127.0.0.1/index/hook/on_stream_not_found
+ */
+ @JSONField(name = "hook.on_stream_not_found")
+ private String hookOnStreamNotFound;
+ /**
+ * 发送rtp(startSendRtp)被动关闭时回调
+ * on_send_rtp_stopped=https://127.0.0.1/index/hook/on_send_rtp_stopped
+ */
+ @JSONField(name = "hook.on_send_rtp_stopped")
+ private String hookOnSendRtpStopped;
+ /**
+ * hook api最大等待回复时间,单位秒
+ * timeoutSec=10
+ */
+ @JSONField(name = "hook.timeoutSec")
+ private Integer hookTimeoutSec;
+ /**
+ * keepalive hook触发间隔,单位秒,float类型
+ * alive_interval=10.0
+ */
+ @JSONField(name = "hook.alive_interval")
+ private Float hookAliveInterval;
+ /**
+ * hook通知失败重试次数,正整数。为0不重试,1时重试一次,以此类推
+ * retry=1
+ */
+ @JSONField(name = "hook.retry")
+ private Integer hookRetry;
+ /**
+ * hook通知失败重试延时,单位秒,float型
+ * retry_delay=3.0
+ */
+ @JSONField(name = "hook.retry_delay")
+ private Float hookRetryDelay;
+ // ----------------------------------------------- cluster -----------------------------------------------
+ /**
+ * 设置源站拉流url模板, 格式跟printf类似,第一个%s指定app,第二个%s指定stream_id,
+ * 开启集群模式后,on_stream_not_found和on_stream_none_reader hook将无效.
+ * 溯源模式支持以下类型:
+ * rtmp方式: rtmp://127.0.0.1:1935/%s/%s
+ * rtsp方式: rtsp://127.0.0.1:554/%s/%s
+ * hls方式: http://127.0.0.1:80/%s/%s/hls.m3u8
+ * http-ts方式: http://127.0.0.1:80/%s/%s.live.ts
+ * 支持多个源站,不同源站通过分号(;)分隔
+ * origin_url=
+ */
+ @JSONField(name = "cluster.origin_url")
+ private String clusterOriginUrl;
+ /**
+ * 溯源总超时时长,单位秒,float型;假如源站有3个,那么单次溯源超时时间为timeout_sec除以3
+ * 单次溯源超时时间不要超过general.maxStreamWaitMS配置
+ * timeout_sec=15
+ */
+ @JSONField(name = "cluster.timeout_sec")
+ private Integer clusterTimeoutSec;
+ /**
+ * 溯源失败尝试次数,-1时永久尝试
+ * retry_count=3
+ */
+ @JSONField(name = "cluster.retry_count")
+ private Integer clusterRetryCount;
+ // ----------------------------------------------- http -----------------------------------------------
+ /**
+ * http服务器字符编码,windows上默认gb2312
+ * charSet=utf-8
+ */
+ @JSONField(name = "http.charSet")
+ private String httpCharSet;
+ /**
+ * http链接超时时间
+ * keepAliveSecond=30
+ */
+ @JSONField(name = "http.keepAliveSecond")
+ private Integer httpKeepAliveSecond;
+ /**
+ * http请求体最大字节数,如果post的body太大,则不适合缓存body在内存
+ * maxReqSize=40960
+ */
+ @JSONField(name = "http.maxReqSize")
+ private Integer httpMaxReqSize;
+ /**
+ * 404网页内容,用户可以自定义404网页
+ * notFound=404 Not Found您访问的资源不存在!
ZLMediaKit-4.0
+ */
+ @JSONField(name = "http.notFound")
+ private String httpNotFound;
+ /**
+ * http服务器监听端口
+ * port=80
+ */
+ @JSONField(name = "http.port")
+ private Integer httpPort;
+ /**
+ * http文件服务器根目录
+ * 可以为相对(相对于本可执行程序目录)或绝对路径
+ * rootPath=./www
+ */
+ @JSONField(name = "http.rootPath")
+ private String httpRootPath;
+ /**
+ * http文件服务器读文件缓存大小,单位BYTE,调整该参数可以优化文件io性能
+ * sendBufSize=65536
+ */
+ @JSONField(name = "http.sendBufSize")
+ private Integer httpSendBufSize;
+ /**
+ * https服务器监听端口
+ * sslport=443
+ */
+ @JSONField(name = "http.sslport")
+ private Integer httpSslPort;
+ /**
+ * 是否显示文件夹菜单,开启后可以浏览文件夹
+ * dirMenu=1
+ */
+ @JSONField(name = "http.dirMenu")
+ private Integer httpDirMenu;
+ /**
+ * 虚拟目录, 虚拟目录名和文件路径使用","隔开,多个配置路径间用";"隔开
+ * 例如赋值为 app_a,/path/to/a;app_b,/path/to/b 那么
+ * 访问 http://127.0.0.1/app_a/file_a 对应的文件路径为 /path/to/a/file_a
+ * 访问 http://127.0.0.1/app_b/file_b 对应的文件路径为 /path/to/b/file_b
+ * 访问其他http路径,对应的文件路径还是在rootPath内
+ * virtualPath=
+ */
+ @JSONField(name = "http.virtualPath")
+ private String httpVirtualPath;
+ /**
+ * 禁止后缀的文件使用mmap缓存,使用“,”隔开
+ * 例如赋值为 .mp4,.flv
+ * 那么访问后缀为.mp4与.flv 的文件不缓存
+ * forbidCacheSuffix=
+ */
+ @JSONField(name = "http.forbidCacheSuffix")
+ private String httpForbidCacheSuffix;
+ /**
+ * 可以把http代理前真实客户端ip放在http头中:https://github.com/ZLMediaKit/ZLMediaKit/issues/1388
+ * 切勿暴露此key,否则可能导致伪造客户端ip
+ * forwarded_ip_header=
+ */
+ @JSONField(name = "http.forwarded_ip_header")
+ private String httpForwardedIpHeader;
+ // ----------------------------------------------- multicast -----------------------------------------------
+ /**
+ * rtp组播截止组播ip地址
+ * addrMax=239.255.255.255
+ */
+ @JSONField(name = "multicast.addrMax")
+ private String multicastAddrMax;
+ /**
+ * rtp组播起始组播ip地址
+ * addrMin=239.0.0.0
+ */
+ @JSONField(name = "multicast.addrMin")
+ private String multicastAddrMin;
+ /**
+ * 组播udp ttl
+ * udpTTL=64
+ */
+ @JSONField(name = "multicast.udpTTL")
+ private Integer multicastUdpTtl;
+ // ----------------------------------------------- record -----------------------------------------------
+ /**
+ * mp4录制或mp4点播的应用名,通过限制应用名,可以防止随意点播
+ * 点播的文件必须放置在此文件夹下
+ * appName=record
+ */
+ @JSONField(name = "record.appName")
+ private String recordAppName;
+ /**
+ * mp4录制写文件缓存,单位BYTE,调整参数可以提高文件io性能
+ * fileBufSize=65536
+ */
+ @JSONField(name = "record.fileBufSize")
+ private Integer recordFileBufSize;
+ /**
+ * mp4录制保存、mp4点播根路径
+ * 可以为相对(相对于本可执行程序目录)或绝对路径
+ * filePath=./www
+ */
+ @JSONField(name = "record.filePath")
+ private String recordFilePath;
+ /**
+ * mp4录制切片时间,单位秒
+ * fileSecond=3600
+ */
+ @JSONField(name = "record.fileSecond")
+ private Integer recordFileSecond;
+ /**
+ * mp4点播每次流化数据量,单位毫秒,
+ * 减少该值可以让点播数据发送量更平滑,增大该值则更节省cpu资源
+ * sampleMS=500
+ */
+ @JSONField(name = "record.sampleMS")
+ private Integer recordSampleMs;
+ /**
+ * mp4录制完成后是否进行二次关键帧索引写入头部
+ * fastStart=0
+ */
+ @JSONField(name = "record.fastStart")
+ private Integer recordFastStart;
+ /**
+ * MP4点播(rtsp/rtmp/http-flv/ws-flv)是否循环播放文件
+ * fileRepeat=0
+ */
+ @JSONField(name = "record.fileRepeat")
+ private Integer recordFileRepeat;
+ /**
+ * MP4录制是否当做播放器参与播放人数统计
+ * mp4_as_player=0
+ */
+ @JSONField(name = "record.mp4_as_player")
+ private Integer recordMp4AsPlayer;
+ // ----------------------------------------------- rtmp -----------------------------------------------
+ /**
+ * rtmp必须在此时间内完成握手,否则服务器会断开链接,单位秒
+ * handshakeSecond=15
+ */
+ @JSONField(name = "rtmp.handshakeSecond")
+ private Integer rtmpHandshakeSecond;
+ /**
+ * rtmp超时时间,如果该时间内未收到客户端的数据,
+ * 或者tcp发送缓存超过这个时间,则会断开连接,单位秒
+ * keepAliveSecond=15
+ */
+ @JSONField(name = "rtmp.keepAliveSecond")
+ private Integer rtmpKeepAliveSecond;
+ /**
+ * 在接收rtmp推流时,是否重新生成时间戳(很多推流器的时间戳着实很烂)
+ * modifyStamp=0
+ */
+ @JSONField(name = "rtmp.modifyStamp")
+ private Integer rtmpModifyStamp;
+ /**
+ * rtmp服务器监听端口
+ * port=1935
+ */
+ @JSONField(name = "rtmp.port")
+ private Integer rtmpPort = 0;
+ /**
+ * rtmps服务器监听地址
+ * sslport=0
+ */
+ @JSONField(name = "rtmp.sslport")
+ private Integer rtmpSslPort = 0;
+ // ----------------------------------------------- rtp -----------------------------------------------
+ /**
+ * 音频mtu大小,该参数限制rtp最大字节数,推荐不要超过1400
+ * 加大该值会明显增加直播延时
+ * audioMtuSize=600
+ */
+ @JSONField(name = "rtp.audioMtuSize")
+ private Integer rtpAudioMtuSize;
+ /**
+ * 视频mtu大小,该参数限制rtp最大字节数,推荐不要超过1400
+ * videoMtuSize=1400
+ */
+ @JSONField(name = "rtp.videoMtuSize")
+ private Integer rtpVideoMtuSize;
+ /**
+ * rtp包最大长度限制,单位KB,主要用于识别TCP上下文破坏时,获取到错误的rtp
+ * rtpMaxSize=10
+ */
+ @JSONField(name = "rtp.rtpMaxSize")
+ private Integer rtpMaxSize;
+ // ----------------------------------------------- rtp_proxy -----------------------------------------------
+ /**
+ * 导出调试数据(包括rtp/ps/h264)至该目录,置空则关闭数据导出
+ * dumpDir=
+ */
+ @JSONField(name = "rtp_proxy.dumpDir")
+ private String proxyDumpDir;
+ /**
+ * udp和tcp代理服务器,支持rtp(必须是ts或ps类型)代理
+ * port=10000
+ */
+ @JSONField(name = "rtp_proxy.port")
+ private Integer proxyPort;
+ /**
+ * rtp超时时间,单位秒
+ * timeoutSec=15
+ */
+ @JSONField(name = "rtp_proxy.timeoutSec")
+ private Integer proxyTimeoutSec;
+ /**
+ * 随机端口范围,最少确保36个端口
+ * 该范围同时限制rtsp服务器udp端口范围
+ * port_range=30000-35000
+ */
+ @JSONField(name = "rtp_proxy.port_range")
+ private String proxyPortRange;
+ /**
+ * rtp h264 负载的pt
+ * h264_pt=98
+ */
+ @JSONField(name = "rtp_proxy.h264_pt")
+ private Integer proxyH264Pt;
+ /**
+ * rtp h265 负载的pt
+ * h265_pt=99
+ */
+ @JSONField(name = "rtp_proxy.h265_pt")
+ private Integer proxyH265Pt;
+ /**
+ * rtp ps 负载的pt
+ * ps_pt=96
+ */
+ @JSONField(name = "rtp_proxy.ps_pt")
+ private Integer proxyPsPt;
+ /**
+ * rtp ts 负载的pt
+ * ts_pt=33
+ */
+ @JSONField(name = "rtp_proxy.ts_pt")
+ private Integer proxyTsPt;
+ /**
+ * rtp opus 负载的pt
+ * opus_pt=100
+ */
+ @JSONField(name = "rtp_proxy.opus_pt")
+ private Integer proxyOpusPt;
+ /**
+ * rtp g711u 负载的pt
+ * g711u_pt=0
+ */
+ @JSONField(name = "rtp_proxy.g711u_pt")
+ private Integer proxyG711UPt;
+ /**
+ * rtp g711a 负载的pt
+ * g711a_pt=8
+ */
+ @JSONField(name = "rtp_proxy.g711a_pt")
+ private Integer proxyG711APt;
+ // ----------------------------------------------- rtc -----------------------------------------------
+ /**
+ * rtc播放推流、播放超时时间
+ * timeoutSec=15
+ */
+ @JSONField(name = "rtc.timeoutSec")
+ private Integer rtcTimeoutSec;
+ /**
+ * 本机对rtc客户端的可见ip,作为服务器时一般为公网ip,可有多个,用','分开,当置空时,会自动获取网卡ip
+ * 同时支持环境变量,以$开头,如"$EXTERN_IP"; 请参考:https://github.com/ZLMediaKit/ZLMediaKit/pull/1786
+ * externIP=
+ */
+ @JSONField(name = "rtc.externIP")
+ private String rtcExternIp;
+ /**
+ * rtc udp服务器监听端口号,所有rtc客户端将通过该端口传输stun/dtls/srtp/srtcp数据,
+ * 该端口是多线程的,同时支持客户端网络切换导致的连接迁移
+ * 需要注意的是,如果服务器在nat内,需要做端口映射时,必须确保外网映射端口跟该端口一致
+ * port=8000
+ */
+ @JSONField(name = "rtc.port")
+ private Integer rtcPort;
+ /**
+ * 设置remb比特率,非0时关闭twcc并开启remb。该设置在rtc推流时有效,可以控制推流画质
+ * 目前已经实现twcc自动调整码率,关闭remb根据真实网络状况调整码率
+ * rembBitRate=0
+ */
+ @JSONField(name = "rtc.rembBitRate")
+ private Integer rtcRembBitRate;
+ /**
+ * rtc支持的音频codec类型,在前面的优先级更高
+ * 以下范例为所有支持的音频codec
+ * preferredCodecA=PCMU,PCMA,opus,mpeg4-generic
+ */
+ @JSONField(name = "rtc.preferredCodecA")
+ private String rtcPreferredCodecA;
+ /**
+ * rtc支持的视频codec类型,在前面的优先级更高
+ * 以下范例为所有支持的视频codec
+ * preferredCodecV=H264,H265,AV1X,VP9,VP8
+ */
+ @JSONField(name = "rtc.preferredCodecV")
+ private String rtcPreferredCodecV;
+ // ----------------------------------------------- srt -----------------------------------------------
+ /**
+ * srt播放推流、播放超时时间,单位秒
+ * timeoutSec=5
+ */
+ @JSONField(name = "srt.timeoutSec")
+ private Integer srtTimeoutSec;
+ /**
+ * srt udp服务器监听端口号,所有srt客户端将通过该端口传输srt数据,
+ * 该端口是多线程的,同时支持客户端网络切换导致的连接迁移
+ * port=9000
+ */
+ @JSONField(name = "srt.port")
+ private Integer srtPort;
+ /**
+ * srt 协议中延迟缓存的估算参数,在握手阶段估算rtt ,然后latencyMul*rtt 为最大缓存时长,此参数越大,表示等待重传的时长就越大
+ * latencyMul=4
+ */
+ @JSONField(name = "srt.latencyMul")
+ private Integer srtLatencyMul;
+ /**
+ * 包缓存的大小
+ * pktBufSize=8192
+ */
+ @JSONField(name = "srt.pktBufSize")
+ private Integer srtPktBufSize;
+ // ----------------------------------------------- rtsp -----------------------------------------------
+ /**
+ * rtsp专有鉴权方式是采用base64还是md5方式
+ * authBasic=0
+ */
+ @JSONField(name = "rtsp.authBasic")
+ private Integer rtspAuthBasic;
+ /**
+ * rtsp拉流、推流代理是否是直接代理模式
+ * 直接代理后支持任意编码格式,但是会导致GOP缓存无法定位到I帧,可能会导致开播花屏
+ * 并且如果是tcp方式拉流,如果rtp大于mtu会导致无法使用udp方式代理
+ * 假定您的拉流源地址不是264或265或AAC,那么你可以使用直接代理的方式来支持rtsp代理
+ * 如果你是rtsp推拉流,但是webrtc播放,也建议关闭直接代理模式,
+ * 因为直接代理时,rtp中可能没有sps pps,会导致webrtc无法播放; 另外webrtc也不支持Single NAL Unit Packets类型rtp
+ * 默认开启rtsp直接代理,rtmp由于没有这些问题,是强制开启直接代理的
+ * directProxy=1
+ */
+ @JSONField(name = "rtsp.directProxy")
+ private Integer rtspDirectProxy;
+ /**
+ * rtsp必须在此时间内完成握手,否则服务器会断开链接,单位秒
+ * handshakeSecond=15
+ */
+ @JSONField(name = "rtsp.handshakeSecond")
+ private Integer rtspHandshakeSecond;
+ /**
+ * rtsp超时时间,如果该时间内未收到客户端的数据,
+ * 或者tcp发送缓存超过这个时间,则会断开连接,单位秒
+ * keepAliveSecond=15
+ */
+ @JSONField(name = "rtsp.keepAliveSecond")
+ private Integer rtspKeepAliveSecond;
+ /**
+ * rtsp服务器监听地址
+ * port=554
+ */
+ @JSONField(name = "rtsp.port")
+ private Integer rtspPort = 0;
+ /**
+ * rtsps服务器监听地址
+ * sslport=0
+ */
+ @JSONField(name = "rtsp.sslport")
+ private Integer rtspSslPort = 0;
+ // ----------------------------------------------- shell -----------------------------------------------
+ /**
+ * 调试telnet服务器接受最大bufffer大小
+ * maxReqSize=1024
+ */
+ @JSONField(name = "shell.maxReqSize")
+ private Integer shellMaxReqSize;
+ /**
+ * 调试telnet服务器监听端口
+ * port=0
+ */
+ @JSONField(name = "shell.port")
+ private Integer shellPort;
+
+ public void refreshHook(String ip, String port, StreamMediaServerConfig server) {
+ String host = ip + ":" + port;
+ this.hookOnFlowReport = StrUtil.format("http://{}/index/hook/on_flow_report", host);
+ this.hookOnHttpAccess = StrUtil.format("http://{}/index/hook/on_http_access", host);
+ this.hookOnPlay = StrUtil.format("http://{}/index/hook/on_play", host);
+ this.hookOnPublish = StrUtil.format("http://{}/index/hook/on_publish", host);
+ this.hookOnRecordMp4 = StrUtil.format("http://{}/index/hook/on_record_mp4", host);
+ this.hookOnRecordTs = StrUtil.format("http://{}/index/hook/on_record_ts", host);
+ this.hookOnRtspAuth = StrUtil.format("http://{}/index/hook/on_rtsp_auth", host);
+ this.hookOnRtspRealm = StrUtil.format("http://{}/index/hook/on_rtsp_realm", host);
+ this.hookOnShellLogin = StrUtil.format("http://{}/index/hook/on_shell_login", host);
+ this.hookOnStreamChanged = StrUtil.format("http://{}/index/hook/on_stream_changed", host);
+ this.hookOnStreamNoneReader = StrUtil.format("http://{}/index/hook/on_stream_none_reader", host);
+ this.hookOnStreamNotFound = StrUtil.format("http://{}/index/hook/on_stream_not_found", host);
+ this.hookOnServerStarted = StrUtil.format("http://{}/index/hook/on_server_started", host);
+ this.hookOnServerKeepalive = StrUtil.format("http://{}/index/hook/on_server_keepalive", host);
+// this.hookOnSendRtpStopped = StrUtil.format("http://{}/index/hook/on_send_rtp_stopped", host);
+ this.hookOnSendRtpStopped = "";
+ }
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/ServerInfo.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/ServerInfo.java
new file mode 100644
index 0000000..143b1fc
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/ServerInfo.java
@@ -0,0 +1,30 @@
+package com.dite.znpt.monitor.media.zlm.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/30 10:50
+ * @Description: 节点基础信息
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class ServerInfo implements Serializable {
+ /**
+ * 节点地址
+ */
+ private String apiHost;
+ /**
+ * 节点端口
+ */
+ private Integer apiPort;
+ /**
+ * 节点秘钥
+ */
+ private String secretKey;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/ServerItem.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/ServerItem.java
new file mode 100644
index 0000000..d590d3f
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/ServerItem.java
@@ -0,0 +1,108 @@
+package com.dite.znpt.monitor.media.zlm.dto;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.core.util.StrUtil;
+import com.dite.znpt.exception.ServiceException;
+import com.dite.znpt.monitor.domain.vo.video.StreamMediaFormat;
+import com.dite.znpt.monitor.media.zlm.config.StreamMediaServerConfig;
+import com.dite.znpt.monitor.media.zlm.dto.resp.MediaResp;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/30 10:50
+ * @Description: 节点信息
+ */
+@Data
+@NoArgsConstructor
+public class ServerItem implements Serializable {
+
+ private static final long serialVersionUID = 2460404295026548536L;
+ /**
+ * 播流最大并发个数
+ */
+ public static final Integer MAX_PLAY_COUNT = 10000;
+ /**
+ * 节点信息ID
+ */
+ private String configId;
+ /**
+ * 流ID前缀
+ */
+ private String streamPrefix;
+ /**
+ * 节点信息ID
+ */
+ private ServerInfo server;
+ /**
+ * 节点格式信息
+ */
+ private List formatList;
+ /**
+ * 节点配置信息
+ */
+ private ServerConfig config;
+ /**
+ * 当前流信息
+ */
+ private List media;
+ /**
+ * 节点状态是否正常
+ */
+ private Boolean status;
+ /**
+ * 流媒体服务器已用的会话句柄
+ */
+ private Set usedSn;
+
+ public ServerItem(StreamMediaServerConfig server, List formatList) {
+ this.streamPrefix = server.getStreamPrefix();
+ this.server = new ServerInfo(server.getApiHost(), server.getApiPort(), server.getSecretKey());
+ this.formatList = formatList;
+ this.status = false;
+ this.usedSn = new HashSet<>();
+ }
+
+ public String genPlaySsrc(String channelCode) {
+ if (this.usedSn.size() >= MAX_PLAY_COUNT) {
+ throw new ServiceException("ssrc已经用完!");
+ }
+ int sn;
+ for (sn = 0; sn < MAX_PLAY_COUNT; sn++) {
+ if (!this.usedSn.contains(sn)) {
+ this.usedSn.add(sn);
+ break;
+ }
+ }
+ //return StrUtil.format("0{}{}", StrUtil.blankToDefault(streamPrefix, channelCode.substring(3, 8)), NumberUtil.decimalFormat("0000", sn));
+ return channelCode;
+ }
+
+ public void releaseSsrc(String ssrc) {
+ try {
+ Integer sn = NumberUtil.parseInt(ssrc.substring(6));
+ usedSn.remove(sn);
+ } catch (Exception ignored) {
+ }
+ }
+
+ public void setMedia(List media) {
+ this.media = media;
+ if (CollUtil.isNotEmpty(media)) {
+ media.forEach(item -> {
+ try {
+ Integer sn = NumberUtil.parseInt(StrUtil.isBlank(streamPrefix) ? item.getStream().substring(6) : item.getStream().replace("0" + streamPrefix, ""));
+ usedSn.add(sn);
+ } catch (Exception ignored) {
+ }
+ });
+ }
+ }
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/BaseEventReq.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/BaseEventReq.java
new file mode 100644
index 0000000..a4125ae
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/BaseEventReq.java
@@ -0,0 +1,48 @@
+package com.dite.znpt.monitor.media.zlm.dto.event;
+
+import lombok.Data;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/30 9:24
+ * @Description:
+ */
+@Data
+public class BaseEventReq {
+ /**
+ * 服务器id,通过配置文件设置
+ */
+ private String mediaServerId;
+ /**
+ * 流应用名
+ */
+ private String app;
+ /**
+ * TCP链接唯一ID
+ */
+ private String id;
+ /**
+ * 播放器ip
+ */
+ private String ip;
+ /**
+ * 播放url参数
+ */
+ private String params;
+ /**
+ * 播放器端口号
+ */
+ private Integer port;
+ /**
+ * 播放的协议,可能是rtsp、rtmp、http
+ */
+ private String schema;
+ /**
+ * 流ID
+ */
+ private String stream;
+ /**
+ * 流虚拟主机
+ */
+ private String vhost;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/BaseEventResp.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/BaseEventResp.java
new file mode 100644
index 0000000..04b573f
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/BaseEventResp.java
@@ -0,0 +1,42 @@
+package com.dite.znpt.monitor.media.zlm.dto.event;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/29 10:33
+ * @Description: 请求响应基类
+ */
+@Data
+@Accessors(chain = true)
+public class BaseEventResp {
+ /**
+ * code == 0时代表完全成功
+ */
+ private Integer code;
+ /**
+ * 失败提示
+ */
+ private String msg;
+ /**
+ * 失败具体原因
+ */
+ private String err;
+ /**
+ * 该rtsp流是否需要rtsp专有鉴权,空字符串代码不需要鉴权
+ */
+ private String realm;
+ /**
+ * 是否关闭推流或拉流
+ */
+ private Boolean close;
+
+ public BaseEventResp setSuccess(){
+ return this.setCode(0).setMsg("success").setErr("");
+ }
+
+ public static BaseEventResp success() {
+ return new BaseEventResp().setSuccess();
+ }
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/FlowReportReq.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/FlowReportReq.java
new file mode 100644
index 0000000..1661a94
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/FlowReportReq.java
@@ -0,0 +1,26 @@
+package com.dite.znpt.monitor.media.zlm.dto.event;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/30 9:04
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class FlowReportReq extends BaseEventReq {
+ /**
+ * tcp链接维持时间,单位秒
+ */
+ private Integer duration;
+ /**
+ * true为播放器,false为推流器
+ */
+ private Boolean player;
+ /**
+ * 耗费上下行流量总和,单位字节
+ */
+ private Integer totalBytes;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/HttpAccessReq.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/HttpAccessReq.java
new file mode 100644
index 0000000..dfae6d6
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/HttpAccessReq.java
@@ -0,0 +1,29 @@
+package com.dite.znpt.monitor.media.zlm.dto.event;
+
+import cn.hutool.core.lang.Dict;
+import com.alibaba.fastjson.annotation.JSONField;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/30 9:10
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class HttpAccessReq extends BaseEventReq {
+ /**
+ * http客户端请求header
+ */
+ private Dict header;
+ /**
+ * 访问路径是文件还是目录
+ */
+ @JSONField(name = "is_dir")
+ private Boolean isDir;
+ /**
+ * 请求访问的文件或目录
+ */
+ private String path;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/HttpAccessResp.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/HttpAccessResp.java
new file mode 100644
index 0000000..51424d8
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/HttpAccessResp.java
@@ -0,0 +1,34 @@
+package com.dite.znpt.monitor.media.zlm.dto.event;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/30 9:15
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@Accessors(chain = true)
+public class HttpAccessResp extends BaseEventResp {
+ /**
+ * 该客户端能访问或被禁止的顶端目录,如果为空字符串,则表述为当前目录
+ */
+ private String path;
+ /**
+ * 本次授权结果的有效期,单位秒
+ */
+ private Integer second;
+ /**
+ * 服务器id,通过配置文件设置
+ */
+ private String mediaServerId;
+
+ public static HttpAccessResp success() {
+ HttpAccessResp resp = new HttpAccessResp();
+ resp.setSuccess();
+ return resp.setSecond(600).setPath("");
+ }
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/PlayReq.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/PlayReq.java
new file mode 100644
index 0000000..2531052
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/PlayReq.java
@@ -0,0 +1,14 @@
+package com.dite.znpt.monitor.media.zlm.dto.event;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/30 9:19
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class PlayReq extends BaseEventReq {
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/PublishReq.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/PublishReq.java
new file mode 100644
index 0000000..de324dc
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/PublishReq.java
@@ -0,0 +1,14 @@
+package com.dite.znpt.monitor.media.zlm.dto.event;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/30 9:57
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class PublishReq extends BaseEventReq{
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/PublishResp.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/PublishResp.java
new file mode 100644
index 0000000..f16d943
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/PublishResp.java
@@ -0,0 +1,81 @@
+package com.dite.znpt.monitor.media.zlm.dto.event;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/30 9:27
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class PublishResp extends BaseEventResp {
+ /**
+ * 是否转换成hls协议
+ */
+ @JSONField(name = "enable_hls")
+ private Boolean enableHls;
+ /**
+ * 是否允许mp4录制
+ */
+ @JSONField(name = "enable_mp4")
+ private Boolean enableMp4;
+ /**
+ * 是否转rtsp协议
+ */
+ @JSONField(name = "enable_rtsp")
+ private Boolean enableRtsp;
+ /**
+ * 是否转rtmp/flv协议
+ */
+ @JSONField(name = "enable_rtmp")
+ private Boolean enableRtmp;
+ /**
+ * 是否转http-ts/ws-ts协议
+ */
+ @JSONField(name = "enable_ts")
+ private Boolean enableTs;
+ /**
+ * 是否转http-fmp4/ws-fmp4协议
+ */
+ @JSONField(name = "enable_fmp4")
+ private Boolean enableFmp4;
+ /**
+ * 转协议时是否开启音频
+ */
+ @JSONField(name = "enable_audio")
+ private Boolean enableAudio;
+ /**
+ * 转协议时,无音频是否添加静音aac音频
+ */
+ @JSONField(name = "add_mute_audio")
+ private Boolean addMuteAudio;
+ /**
+ * mp4录制文件保存根目录,置空使用默认
+ */
+ @JSONField(name = "mp4_save_path")
+ private String mp4SavePath;
+ /**
+ * mp4录制切片大小,单位秒
+ */
+ @JSONField(name = "mp4_max_second")
+ private Integer mp4MaxSecond;
+ /**
+ * hls文件保存保存根目录,置空使用默认
+ */
+ @JSONField(name = "hls_save_path")
+ private String hlsSavePath;
+ /**
+ * 断连续推延时,单位毫秒,置空使用配置文件默认值
+ */
+ @JSONField(name = "continue_push_ms")
+ private Long continuePushMs;
+
+ public static PublishResp success() {
+ PublishResp resp = new PublishResp();
+ resp.setSuccess();
+ return resp;
+ }
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/RecordMp4Req.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/RecordMp4Req.java
new file mode 100644
index 0000000..50142ec
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/RecordMp4Req.java
@@ -0,0 +1,48 @@
+package com.dite.znpt.monitor.media.zlm.dto.event;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/30 9:32
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class RecordMp4Req extends BaseEventReq {
+ /**
+ * 文件名
+ */
+ @JSONField(name = "file_name")
+ private String fileName;
+ /**
+ * 文件绝对路径
+ */
+ @JSONField(name = "file_path")
+ private String filePath;
+ /**
+ * 文件大小,单位字节
+ */
+ @JSONField(name = "file_size")
+ private Integer fileSize;
+ /**
+ * 文件所在目录路径
+ */
+ private String folder;
+ /**
+ * 开始录制时间戳
+ */
+ @JSONField(name = "start_time")
+ private Integer startTime;
+ /**
+ * 录制时长,单位秒
+ */
+ @JSONField(name = "time_len")
+ private Integer timeLen;
+ /**
+ * http/rtsp/rtmp点播相对url路径
+ */
+ private String url;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/RtspAuthReq.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/RtspAuthReq.java
new file mode 100644
index 0000000..bcb51e5
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/RtspAuthReq.java
@@ -0,0 +1,30 @@
+package com.dite.znpt.monitor.media.zlm.dto.event;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/30 9:35
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class RtspAuthReq extends BaseEventReq {
+ /**
+ * 请求的密码是否必须为明文(base64鉴权需要明文密码)
+ */
+ @JSONField(name = "must_no_encrypt")
+ private Boolean mustNoEncrypt;
+ /**
+ * rtsp播放鉴权加密realm
+ */
+ private String realm;
+ /**
+ * 播放用户名
+ */
+ @JSONField(name = "user_name")
+ private String userName;
+
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/RtspAuthResp.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/RtspAuthResp.java
new file mode 100644
index 0000000..2021549
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/RtspAuthResp.java
@@ -0,0 +1,30 @@
+package com.dite.znpt.monitor.media.zlm.dto.event;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/30 9:35
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@Accessors(chain = true)
+public class RtspAuthResp extends BaseEventResp {
+ /**
+ * 用户密码
+ */
+ private String passwd;
+ /**
+ * 用户密码是否已加密
+ */
+ private Boolean encrypted;
+
+ public static RtspAuthResp success() {
+ RtspAuthResp resp = new RtspAuthResp();
+ resp.setSuccess();
+ return resp.setEncrypted(false);
+ }
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/RtspRealmReq.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/RtspRealmReq.java
new file mode 100644
index 0000000..8d6547f
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/RtspRealmReq.java
@@ -0,0 +1,14 @@
+package com.dite.znpt.monitor.media.zlm.dto.event;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/30 9:33
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class RtspRealmReq extends BaseEventReq {
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/ServerKeepaliveReq.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/ServerKeepaliveReq.java
new file mode 100644
index 0000000..d023328
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/ServerKeepaliveReq.java
@@ -0,0 +1,16 @@
+package com.dite.znpt.monitor.media.zlm.dto.event;
+
+import com.dite.znpt.monitor.media.zlm.dto.resp.StatisticResp;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/30 9:43
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class ServerKeepaliveReq extends BaseEventReq {
+ private StatisticResp data;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/ShellLoginReq.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/ShellLoginReq.java
new file mode 100644
index 0000000..86016eb
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/ShellLoginReq.java
@@ -0,0 +1,24 @@
+package com.dite.znpt.monitor.media.zlm.dto.event;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/30 9:37
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class ShellLoginReq extends BaseEventReq {
+ /**
+ * 终端登录用户密码
+ */
+ private String passwd;
+ /**
+ * 终端登录用户名
+ */
+ @JSONField(name = "user_name")
+ private String userName;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/StreamChangedReq.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/StreamChangedReq.java
new file mode 100644
index 0000000..cd90632
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/StreamChangedReq.java
@@ -0,0 +1,19 @@
+package com.dite.znpt.monitor.media.zlm.dto.event;
+
+import com.dite.znpt.monitor.media.zlm.dto.resp.MediaResp;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/30 9:38
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class StreamChangedReq extends MediaResp {
+ /**
+ * 流注册或注销
+ */
+ private Boolean regist;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/StreamNoneReaderReq.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/StreamNoneReaderReq.java
new file mode 100644
index 0000000..65e34bf
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/StreamNoneReaderReq.java
@@ -0,0 +1,14 @@
+package com.dite.znpt.monitor.media.zlm.dto.event;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/30 9:40
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class StreamNoneReaderReq extends BaseEventReq {
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/StreamNotFoundReq.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/StreamNotFoundReq.java
new file mode 100644
index 0000000..0ead9cc
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/event/StreamNotFoundReq.java
@@ -0,0 +1,14 @@
+package com.dite.znpt.monitor.media.zlm.dto.event;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/30 9:42
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class StreamNotFoundReq extends BaseEventReq {
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/BaseReq.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/BaseReq.java
new file mode 100644
index 0000000..445aef0
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/BaseReq.java
@@ -0,0 +1,18 @@
+package com.dite.znpt.monitor.media.zlm.dto.req;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/29 10:33
+ * @Description: 请求响应基类
+ */
+@Data
+public class BaseReq implements Serializable {
+ /**
+ * api操作密钥(配置文件配置),如果操作ip是127.0.0.1,则不需要此参数
+ */
+ private String secret;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/CloseStreamReq.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/CloseStreamReq.java
new file mode 100644
index 0000000..2eb3044
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/CloseStreamReq.java
@@ -0,0 +1,18 @@
+package com.dite.znpt.monitor.media.zlm.dto.req;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/29 10:51
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class CloseStreamReq extends StreamReq {
+ /**
+ * 是否强制关闭(有人在观看是否还关闭)
+ */
+ private Integer force;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/FFmpegSourceReq.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/FFmpegSourceReq.java
new file mode 100644
index 0000000..54de5d0
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/FFmpegSourceReq.java
@@ -0,0 +1,45 @@
+package com.dite.znpt.monitor.media.zlm.dto.req;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/29 12:26
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class FFmpegSourceReq extends BaseReq {
+ /**
+ * FFmpeg拉流地址,支持任意协议或格式(只要FFmpeg支持即可)
+ */
+ @JSONField(name = "src_url")
+ private String srcUrl;
+ /**
+ * FFmpeg rtmp推流地址,一般都是推给自己,例如rtmp://127.0.0.1/live/stream_form_ffmpeg
+ */
+ @JSONField(name = "dst_url")
+ private String dstUrl;
+ /**
+ * FFmpeg推流成功超时时间
+ */
+ @JSONField(name = "timeout_ms")
+ private Integer timeoutMs;
+ /**
+ * 是否开启hls录制
+ */
+ @JSONField(name = "enable_hls")
+ private Integer enableHls;
+ /**
+ * 是否开启mp4录制
+ */
+ @JSONField(name = "enable_mp4")
+ private Integer enableMp4;
+ /**
+ * 配置文件中FFmpeg命令参数模板key(非内容),置空则采用默认模板:ffmpeg.cmd
+ */
+ @JSONField(name = "ffmpeg_cmd_key")
+ private String ffmpegCmdKey;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/GetAllSessionReq.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/GetAllSessionReq.java
new file mode 100644
index 0000000..dd01aa5
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/GetAllSessionReq.java
@@ -0,0 +1,25 @@
+package com.dite.znpt.monitor.media.zlm.dto.req;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/29 17:21
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class GetAllSessionReq extends BaseReq{
+ /**
+ *筛选本机端口,例如筛选rtsp链接:554
+ */
+ @JSONField(name = "local_port")
+ private Integer localPort;
+ /**
+ *筛选客户端ip
+ */
+ @JSONField(name = "peer_ip")
+ private String peerIp;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/GetMp4RecordFileReq.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/GetMp4RecordFileReq.java
new file mode 100644
index 0000000..6b05d35
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/GetMp4RecordFileReq.java
@@ -0,0 +1,24 @@
+package com.dite.znpt.monitor.media.zlm.dto.req;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/29 13:04
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class GetMp4RecordFileReq extends StreamReq {
+ /**
+ * 流的录像日期,格式为2020-02-01,如果不是完整的日期,那么是搜索录像文件夹列表,否则搜索对应日期下的mp4文件列表
+ */
+ private String period;
+ /**
+ * 自定义搜索路径,与startRecord方法中的customized_path一样,默认为配置文件的路径
+ */
+ @JSONField(name = "customized_path")
+ private String customizedPath;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/IdReq.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/IdReq.java
new file mode 100644
index 0000000..82c454d
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/IdReq.java
@@ -0,0 +1,20 @@
+package com.dite.znpt.monitor.media.zlm.dto.req;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/29 17:24
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@AllArgsConstructor
+public class IdReq extends BaseReq {
+ /**
+ * 客户端唯一id,可以通过getAllSession接口获取
+ */
+ private Long id;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/KeyReq.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/KeyReq.java
new file mode 100644
index 0000000..91ebcd9
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/KeyReq.java
@@ -0,0 +1,20 @@
+package com.dite.znpt.monitor.media.zlm.dto.req;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/29 17:30
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@AllArgsConstructor
+public class KeyReq extends BaseReq {
+ /**
+ * addStreamProxy接口返回的key
+ */
+ private String key;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/RecordReq.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/RecordReq.java
new file mode 100644
index 0000000..4e3dc21
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/RecordReq.java
@@ -0,0 +1,29 @@
+package com.dite.znpt.monitor.media.zlm.dto.req;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/29 13:11
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class RecordReq extends StreamReq {
+ /**
+ * 0为hls,1为mp4
+ */
+ private Integer type;
+ /**
+ * 录像保存目录
+ */
+ @JSONField(name = "customized_path")
+ private String customizedPath;
+ /**
+ * mp4录像切片时间大小,单位秒,置0则采用配置项
+ */
+ @JSONField(name = "max_second")
+ private Integer maxSecond;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/RtpServerReq.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/RtpServerReq.java
new file mode 100644
index 0000000..a7003e7
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/RtpServerReq.java
@@ -0,0 +1,45 @@
+package com.dite.znpt.monitor.media.zlm.dto.req;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/29 13:17
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@NoArgsConstructor
+public class RtpServerReq extends BaseReq {
+ /**
+ * 接收端口,0则为随机端口
+ */
+ private Integer port;
+ /**
+ * 启用UDP监听的同时是否监听TCP端口
+ */
+ @JSONField(name = "enable_tcp")
+ private Integer enableTcp;
+ /**
+ * 该端口绑定的流ID,该端口只能创建这一个流(而不是根据ssrc创建多个)
+ */
+ @JSONField(name = "stream_id")
+ private String streamId;
+
+ public RtpServerReq(Integer port, Integer enableTcp, String streamId) {
+ this.port = port;
+ this.enableTcp = enableTcp;
+ this.streamId = streamId;
+ }
+
+ public RtpServerReq(Integer enableTcp, String streamId) {
+ this(0, enableTcp, streamId);
+ }
+
+ public RtpServerReq(String streamId) {
+ this(1, streamId);
+ }
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/SendRtpReq.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/SendRtpReq.java
new file mode 100644
index 0000000..20807df
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/SendRtpReq.java
@@ -0,0 +1,53 @@
+package com.dite.znpt.monitor.media.zlm.dto.req;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/29 13:23
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class SendRtpReq extends StreamReq {
+ /**
+ * 推流的rtp的ssrc,指定不同的ssrc可以同时推流到多个服务器
+ */
+ private String ssrc;
+ /**
+ * 目标ip或域名
+ */
+ @JSONField(name = "dst_url")
+ private String dstUrl;
+ /**
+ * 目标端口
+ */
+ @JSONField(name = "dst_port")
+ private Integer dstPort;
+ /**
+ * 是否为udp模式,否则为tcp模式
+ */
+ @JSONField(name = "is_udp")
+ private Integer isUdp;
+ /**
+ * 使用的本机端口,为0或不传时默认为随机端口
+ */
+ @JSONField(name = "src_port")
+ private Integer srcPort;
+ /**
+ * 使用的本机端口,为0或不传时默认为随机端口
+ */
+ private Integer pt;
+ /**
+ * 发送时,rtp的负载类型。为1时,负载为ps;为0时,为es;不传时默认为1
+ */
+ @JSONField(name = "use_ps")
+ private Integer usePs;
+ /**
+ * 当use_ps 为0时,有效。为1时,发送音频;为0时,发送视频;不传时默认为0
+ */
+ @JSONField(name = "only_audio")
+ private Integer onlyAudio;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/SnapReq.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/SnapReq.java
new file mode 100644
index 0000000..548cfd7
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/SnapReq.java
@@ -0,0 +1,29 @@
+package com.dite.znpt.monitor.media.zlm.dto.req;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/29 13:14
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class SnapReq extends BaseReq {
+ /**
+ * 需要截图的url,可以是本机的,也可以是远程主机的
+ */
+ private String url;
+ /**
+ * 截图失败超时时间,防止FFmpeg一直等待截图
+ */
+ @JSONField(name = "timeout_sec")
+ private Integer timeoutSec;
+ /**
+ * 截图的过期时间,该时间内产生的截图都会作为缓存返回
+ */
+ @JSONField(name = "expire_sec")
+ private Integer expireSec;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/StreamIdReq.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/StreamIdReq.java
new file mode 100644
index 0000000..a53d2dc
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/StreamIdReq.java
@@ -0,0 +1,22 @@
+package com.dite.znpt.monitor.media.zlm.dto.req;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/29 17:30
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@AllArgsConstructor
+public class StreamIdReq extends BaseReq {
+ /**
+ * RTP的ssrc,16进制字符串或者是流的id(openRtpServer接口指定)
+ */
+ @JSONField(name = "stream_id")
+ private String streamId;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/StreamProxyReq.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/StreamProxyReq.java
new file mode 100644
index 0000000..8481f0a
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/StreamProxyReq.java
@@ -0,0 +1,89 @@
+package com.dite.znpt.monitor.media.zlm.dto.req;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/29 12:19
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class StreamProxyReq extends StreamReq {
+ /**
+ * 拉流地址,例如rtmp://live.hkstv.hk.lxdns.com/live/hks2 Y
+ */
+ private String url;
+ /**
+ * 拉流重试次数,默认为-1无限重试
+ */
+ @JSONField(name = "retry_count")
+ private Integer retryCount;
+ /**
+ * rtsp拉流时,拉流方式,0:tcp,1:udp,2:组播
+ */
+ @JSONField(name = "rtp_type")
+ private Integer rtpType;
+ /**
+ * 拉流超时时间,单位秒,float类型
+ */
+ @JSONField(name = "timeout_sec")
+ private Integer timeoutSec;
+ /**
+ * 是否转换成hls协议
+ */
+ @JSONField(name = "enable_hls")
+ private Integer enableHls;
+ /**
+ * 是否允许mp4录制
+ */
+ @JSONField(name = "enable_mp4")
+ private Integer enableMp4;
+ /**
+ * 是否转rtsp协议
+ */
+ @JSONField(name = "enable_rtsp")
+ private Integer enableRtsp;
+ /**
+ * 是否转rtmp/flv协议
+ */
+ @JSONField(name = "enable_rtmp")
+ private Integer enableRtmp;
+ /**
+ * 是否转http-ts/ws-ts协议
+ */
+ @JSONField(name = "enable_ts")
+ private Integer enableTs;
+ /**
+ * 是否转http-fmp4/ws-fmp4协议
+ */
+ @JSONField(name = "enable_fmp4")
+ private Integer enableFmp4;
+ /**
+ * 转协议时是否开启音频
+ */
+ @JSONField(name = "enable_audio")
+ private Integer enableAudio;
+ /**
+ * 转协议时,无音频是否添加静音aac音频
+ */
+ @JSONField(name = "add_mute_audio")
+ private Integer addMuteAudio;
+ /**
+ * mp4录制文件保存根目录,置空使用默认
+ */
+ @JSONField(name = "mp4_save_path")
+ private String mp4SavePath;
+ /**
+ * mp4录制切片大小,单位秒
+ */
+ @JSONField(name = "mp4_max_second")
+ private Integer mp4MaxSecond;
+ /**
+ * hls文件保存保存根目录,置空使用默认
+ */
+ @JSONField(name = "hls_save_path")
+ private String hlsSavePath;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/StreamPusherProxyReq.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/StreamPusherProxyReq.java
new file mode 100644
index 0000000..6729ba1
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/StreamPusherProxyReq.java
@@ -0,0 +1,35 @@
+package com.dite.znpt.monitor.media.zlm.dto.req;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/29 13:50
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class StreamPusherProxyReq extends StreamReq {
+ /**
+ * 目标转推url,带参数需要自行url转义
+ */
+ @JSONField(name = "dst_url")
+ private String dstUrl;
+ /**
+ * 转推失败重试次数,默认无限重试
+ */
+ @JSONField(name = "retry_count")
+ private Integer retryCount;
+ /**
+ * rtsp拉流时,拉流方式,0:tcp,1:udp,2:组播
+ */
+ @JSONField(name = "rtp_type")
+ private Integer rtpType;
+ /**
+ * 拉流超时时间,单位秒,float类型
+ */
+ @JSONField(name = "timeout_sec")
+ private Float timeoutSec;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/StreamReq.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/StreamReq.java
new file mode 100644
index 0000000..404369a
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/req/StreamReq.java
@@ -0,0 +1,32 @@
+package com.dite.znpt.monitor.media.zlm.dto.req;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/29 13:05
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@Accessors(chain = true)
+public class StreamReq extends BaseReq {
+ /**
+ * 协议,例如 rtsp或rtmp
+ */
+ private String schema;
+ /**
+ * 筛选虚拟主机,例如__defaultVhost__
+ */
+ private String vhost;
+ /**
+ * 筛选应用名,例如 live
+ */
+ private String app;
+ /**
+ * 筛选流id,例如 test
+ */
+ private String stream;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/resp/BaseResp.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/resp/BaseResp.java
new file mode 100644
index 0000000..d6cfa48
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/resp/BaseResp.java
@@ -0,0 +1,64 @@
+package com.dite.znpt.monitor.media.zlm.dto.resp;
+
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/29 10:33
+ * @Description: 请求响应基类
+ */
+@Data
+public class BaseResp {
+ /**
+ * code == 0时代表完全成功
+ */
+ private Integer code;
+ /**
+ * 失败提示
+ */
+ private String msg;
+ /**
+ * 失败具体原因
+ */
+ private String result;
+ /**
+ * 返回数据
+ */
+ private String data;
+ /**
+ * 配置项变更个数
+ */
+ private Integer changed;
+ /**
+ * false:未录制,true:正在录制
+ */
+ private Boolean status;
+ /**
+ * 接收端口,方便获取随机端口号
+ */
+ private Integer port;
+ /**
+ * 是否找到记录并关闭
+ */
+ private Integer hit;
+
+ public String getMsg() {
+ return StrUtil.format("{}:{}", code, msg);
+ }
+
+ public Boolean isSuccess() {
+ return code == 0;
+ }
+
+ public T getData(Class clazz) {
+ return JSON.parseObject(data, clazz);
+ }
+
+ public List getList(Class clazz) {
+ return JSON.parseArray(data, clazz);
+ }
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/resp/CloseStreamResp.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/resp/CloseStreamResp.java
new file mode 100644
index 0000000..aa0bf8e
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/resp/CloseStreamResp.java
@@ -0,0 +1,25 @@
+package com.dite.znpt.monitor.media.zlm.dto.resp;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/29 11:59
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class CloseStreamResp extends BaseResp {
+ /**
+ * 筛选命中的流个数
+ */
+ @JSONField(name = "count_hit")
+ private Integer countHit;
+ /**
+ * 被关闭的流个数,可能小于count_hit
+ */
+ @JSONField(name = "count_closed")
+ private Integer countClosed;
+}
diff --git a/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/resp/MediaResp.java b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/resp/MediaResp.java
new file mode 100644
index 0000000..942b099
--- /dev/null
+++ b/sip/src/main/java/com/dite/znpt/monitor/media/zlm/dto/resp/MediaResp.java
@@ -0,0 +1,61 @@
+package com.dite.znpt.monitor.media.zlm.dto.resp;
+
+import com.dite.znpt.monitor.media.zlm.dto.event.BaseEventReq;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @Author: huise23
+ * @Date: 2022/8/29 11:18
+ * @Description:
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class MediaResp extends BaseEventReq implements Serializable {
+ private static final long serialVersionUID = -8710934021370904914L;
+
+ /**
+ * 本协议观看人数
+ */
+ private Integer readerCount;
+ /**
+ * 观看总人数,包括hls/rtsp/rtmp/http-flv/ws-flv
+ */
+ private Integer totalReaderCount;
+ /**
+ * 客户端和服务器网络信息,可能为null类型
+ */
+ private OriginSock originSock;
+ /**
+ * 产生源类型,包括 unknown = 0, rtmp_push = 1, rtsp_push = 2, rtp_push = 3, pull = 4, ffmpeg_pull = 5, mp4_vod = 6, device_chn = 7
+ */
+ private Integer originType;
+ /**
+ * 产生源类型
+ */
+ private String originTypeStr;
+ /**
+ * 产生源的url
+ */
+ private String originUrl;
+ /**
+ * GMT unix系统时间戳,单位秒
+ */
+ private Long createStamp;
+ /**
+ * 存活时间,单位秒
+ */
+ private Long aliveSecond;
+ /**
+ * 数据产生速度,单位byte/s
+ */
+ private Long bytesSpeed;
+ /**
+ * 音视频轨道
+ */
+ private List