diff --git a/pom.xml b/pom.xml index 2a53d42b..fd5c0f8f 100644 --- a/pom.xml +++ b/pom.xml @@ -99,6 +99,7 @@ nacos + prod diff --git a/ruoyi-auth/src/main/java/org/dromara/auth/controller/TokenController.java b/ruoyi-auth/src/main/java/org/dromara/auth/controller/TokenController.java index 17a49153..f6359330 100644 --- a/ruoyi-auth/src/main/java/org/dromara/auth/controller/TokenController.java +++ b/ruoyi-auth/src/main/java/org/dromara/auth/controller/TokenController.java @@ -116,6 +116,11 @@ public class TokenController { return R.ok(loginVo); } + /** + * 校验token + * @param token + * @return + */ @RequestMapping("/token/check") public R checkToken(String token) { return R.ok(LoginHelper.getLoginUser(token)); diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/CostMeterWaterController.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/CostMeterWaterController.java index f63a9fb4..9cd89f4f 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/CostMeterWaterController.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/CostMeterWaterController.java @@ -68,7 +68,17 @@ public class CostMeterWaterController extends BaseController { @PathVariable("id") Long id) { return R.ok(costMeterWaterService.queryById(id)); } + /** + * 获取上月费用详情 + * + * + */ + @GetMapping("/ultimoWater/{roomId}") + public R getUltimoWater(@NotNull(message = "房间id不能为空") + @PathVariable("roomId") Long roomId) { + return R.ok(costMeterWaterService.getUltimoWater(roomId)); + } /** * 新增费用-水电抄 */ diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/ServeceCustomerController.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/ServeceCustomerController.java new file mode 100644 index 00000000..65e0362a --- /dev/null +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/ServeceCustomerController.java @@ -0,0 +1,36 @@ +package org.dromara.property.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import lombok.RequiredArgsConstructor; +import org.dromara.common.core.domain.R; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.property.domain.bo.ServerBookingBo; +import org.dromara.property.domain.vo.ServeceCustomerCountVo; +import org.dromara.property.domain.vo.ServerBookingVo; +import org.dromara.property.service.IServiceWorkOrdersService; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Author:yuyongle + * @Date:2025/7/21 15:25 + * @Description:客户服务控制器 + **/ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/serveceCustomer") +public class ServeceCustomerController { + private final IServiceWorkOrdersService serviceWorkOrdersService; + /** + * 查询客户服务工单看板统计 + */ + @GetMapping("/counts") + public R counts() { + return R.ok(serviceWorkOrdersService.counts()); + } + +} diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/AttendanceShift.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/AttendanceShift.java index d71f694b..459ae578 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/AttendanceShift.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/AttendanceShift.java @@ -41,12 +41,12 @@ public class AttendanceShift extends TenantEntity { /** * 考勤开始时间 */ - private DateTime startTime; + private LocalTime startTime; /** * 考勤结束时间 */ - private DateTime endTime; + private LocalTime endTime; /** * 状态(0:off,1:on) @@ -61,12 +61,12 @@ public class AttendanceShift extends TenantEntity { /** * 休息开始时间 */ - private DateTime restStartTime; + private LocalTime restStartTime; /** * 休息结束时间 */ - private DateTime restEndTime; + private LocalTime restEndTime; } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/ServiceWorkOrders.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/ServiceWorkOrders.java index ed5a881c..5fe92a6b 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/ServiceWorkOrders.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/ServiceWorkOrders.java @@ -47,7 +47,7 @@ public class ServiceWorkOrders extends TenantEntity { /** * 状态 */ - private Integer status; + private String status; /** * 派单时间 @@ -55,15 +55,19 @@ public class ServiceWorkOrders extends TenantEntity { private Date dispatchTime; /** - * 发起人姓名 + * 发起人 */ - private String initiatorName; + private String initiatorPeople; /** * 处理人姓名 */ - private String handler; + private long handler; + /** + * 抄送人 + */ + private long ccPeople; /** * 地址 @@ -88,17 +92,7 @@ public class ServiceWorkOrders extends TenantEntity { /** * 是否超时 */ - private Integer isTimeOut; - - /** - * 创建人id - */ - private Long createById; - - /** - * 更新人id - */ - private Long updateById; + private String isTimeOut; } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/ServiceWorkOrdersRecord.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/ServiceWorkOrdersRecord.java new file mode 100644 index 00000000..9e35cc17 --- /dev/null +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/ServiceWorkOrdersRecord.java @@ -0,0 +1,45 @@ +package org.dromara.property.domain; + +import org.dromara.common.tenant.core.TenantEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; + +/** + * 工单接单记录对象 service_work_orders_record + * + * @author mocheng + * @date 2025-07-21 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("service_work_orders_record") +public class ServiceWorkOrdersRecord extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId(value = "id") + private Long id; + + /** + * 工单id + */ + private Long orderId; + + + /** + * 状态(0创建工单,1已派单2已抢单3处理中,4已完成) + */ + private String status; + + /** + * 处理人 + */ + private Long handler; +} diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/ServiceWorkOrdersType.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/ServiceWorkOrdersType.java index ea18036f..95677afb 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/ServiceWorkOrdersType.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/ServiceWorkOrdersType.java @@ -57,16 +57,6 @@ public class ServiceWorkOrdersType extends TenantEntity { */ private Integer isTransfers; - /** - * 创建人id - */ - private Long createById; - - /** - * 更新人id - */ - private Long updateById; - /** * 搜索值 */ diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/AttendanceShiftBo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/AttendanceShiftBo.java index cded8be8..cf4f513d 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/AttendanceShiftBo.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/AttendanceShiftBo.java @@ -42,13 +42,13 @@ public class AttendanceShiftBo extends BaseEntity { * 考勤开始时间 */ @DateTimeFormat(pattern = "HH:mm:ss") - private DateTime startTime; + private LocalTime startTime; /** * 考勤结束时间 */ @DateTimeFormat(pattern = "HH:mm:ss") - private DateTime endTime; + private LocalTime endTime; /** * 状态(0:off,1:on) @@ -64,13 +64,13 @@ public class AttendanceShiftBo extends BaseEntity { * 休息开始时间 */ @DateTimeFormat(pattern = "HH:mm:ss") - private DateTime restStartTime; + private LocalTime restStartTime; /** * 休息结束时间 */ @DateTimeFormat(pattern = "HH:mm:ss") - private DateTime restEndTime; + private LocalTime restEndTime; } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/CostReturnPayFeeBo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/CostReturnPayFeeBo.java index 9106436d..3e5b944d 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/CostReturnPayFeeBo.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/CostReturnPayFeeBo.java @@ -34,7 +34,14 @@ public class CostReturnPayFeeBo extends BaseEntity { */ @NotBlank(message = "退款单号不能为空", groups = { AddGroup.class, EditGroup.class }) private String returnNo; - + /** + * 收费id + */ + private Long chargeId; + /** + * 收费类型 + */ + private String chargeType; /** * 支付单号 */ diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/ServiceWorkOrdersBo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/ServiceWorkOrdersBo.java index 4fbf80cf..dc33ecea 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/ServiceWorkOrdersBo.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/ServiceWorkOrdersBo.java @@ -36,17 +36,19 @@ public class ServiceWorkOrdersBo extends BaseEntity { /** * 工单名称 */ + @NotNull(message = "工单名称不能为空", groups = { EditGroup.class }) private String orderName; /** * 工单类型 */ + @NotNull(message = "工单类型不能为空", groups = { EditGroup.class }) private Long type; /** * 状态 */ - private Integer status; + private String status; /** * 派单时间 @@ -62,16 +64,19 @@ public class ServiceWorkOrdersBo extends BaseEntity { /** * 处理人姓名 */ - private String handler; + private Long handler; /** * 地址 */ + @NotNull(message = "地址不能为空", groups = { EditGroup.class }) + private String location; /** * 计划完成时间 */ + @NotNull(message = "计划完成时间不能为空", groups = { EditGroup.class }) private Date planCompleTime; /** @@ -87,18 +92,6 @@ public class ServiceWorkOrdersBo extends BaseEntity { /** * 是否超时 */ - private Integer isTimeOut; - - /** - * 创建人id - */ - private Long createById; - - /** - * 更新人id - */ - private Long updateById; - - + private String isTimeOut; } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/ServiceWorkOrdersRecordBo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/ServiceWorkOrdersRecordBo.java new file mode 100644 index 00000000..0575d095 --- /dev/null +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/ServiceWorkOrdersRecordBo.java @@ -0,0 +1,53 @@ +package org.dromara.property.domain.bo; + +import org.dromara.property.domain.ServiceWorkOrdersRecord; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; + +/** + * 工单接单记录业务对象 service_work_orders_record + * + * @author mocheng + * @date 2025-07-21 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = ServiceWorkOrdersRecord.class, reverseConvertGenerate = false) +public class ServiceWorkOrdersRecordBo extends BaseEntity { + + /** + * id + */ + @NotNull(message = "id不能为空", groups = { EditGroup.class }) + private Long id; + + /** + * 工单id + */ + @NotBlank(message = "工单id不能为空", groups = { AddGroup.class, EditGroup.class }) + private long orderId; + + /** + * 状态(0创建工单,1已派单2已抢单3处理中,4已完成) + */ + @NotBlank(message = "状态(0创建工单,1已派单2已抢单3处理中,4已完成)不能为空", groups = { AddGroup.class, EditGroup.class }) + private String status; + + /** + * 处理人 + */ + @NotNull(message = "处理人不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long handler; + + /** + * 搜索值 + */ + private String searchValue; + + +} diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/ServiceWorkOrdersTypeBo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/ServiceWorkOrdersTypeBo.java index d02facda..ab0d9a20 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/ServiceWorkOrdersTypeBo.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/ServiceWorkOrdersTypeBo.java @@ -60,19 +60,4 @@ public class ServiceWorkOrdersTypeBo extends BaseEntity { */ private Integer isTransfers; - /** - * 创建人id - */ - private Long createById; - - /** - * 更新人id - */ - private Long updateById; - - /** - * 搜索值 - */ - private String searchValue; - } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/AttendanceShiftVo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/AttendanceShiftVo.java index ac256f93..6bf0f594 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/AttendanceShiftVo.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/AttendanceShiftVo.java @@ -49,13 +49,13 @@ public class AttendanceShiftVo implements Serializable { * 考勤开始时间 */ @ExcelProperty(value = "考勤开始时间") - private DateTime startTime; + private LocalTime startTime; /** * 考勤结束时间 */ @ExcelProperty(value = "考勤结束时间") - private DateTime endTime; + private LocalTime endTime; /** * 状态(0:off,1:on) @@ -75,13 +75,13 @@ public class AttendanceShiftVo implements Serializable { * 休息开始时间 */ @ExcelProperty(value = "休息开始时间") - private DateTime restStartTime; + private LocalTime restStartTime; /** * 休息结束时间 */ @ExcelProperty(value = "休息结束时间") - private DateTime restEndTime; + private LocalTime restEndTime; } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServeceCustomerCountVo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServeceCustomerCountVo.java new file mode 100644 index 00000000..60034545 --- /dev/null +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServeceCustomerCountVo.java @@ -0,0 +1,52 @@ +package org.dromara.property.domain.vo; + +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + * @Author:yuyongle + * @Date:2025/7/21 15:29 + * @Description:客户服务工单统计看板 + **/ +@Data +@Accessors(chain = true) +public class ServeceCustomerCountVo implements Serializable { + /** + * 工单总数 + */ + private Integer workOrdersTotal; + /** + * 未派工单总数 + */ + private Integer notWorkOrdersTotal; + /** + * 未半结超时工单 + */ + private Integer novertimeOrdersTotal; + /** + * 处理中工单 + */ + private Integer InHandOrdersTotal; + /** + * 当月工单超时率 + */ + private Integer novertimeOrdersRate; + /** + * 当月工单数 + */ + private Integer monthOrdersTotal; + /** + * 超时工单数 + */ + private Integer outTimeOrdersTotal; + /** + * 当月满意度 + */ + private Integer monthoSatisfaction; + /** + * 满意数 + */ + private Integer satisfaction; +} diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrdersInfoVo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrdersInfoVo.java index 72ebaada..40eca36b 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrdersInfoVo.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrdersInfoVo.java @@ -5,10 +5,12 @@ import cn.idev.excel.annotation.ExcelProperty; import io.github.linpeilie.annotations.AutoMapper; import lombok.Data; import org.dromara.property.domain.ServiceWorkOrders; +import org.dromara.property.domain.ServiceWorkOrdersRecord; import java.io.Serial; import java.io.Serializable; import java.util.Date; +import java.util.List; /** * @Author:yuyongle @@ -51,7 +53,7 @@ public class ServiceWorkOrdersInfoVo implements Serializable { * 状态 */ @ExcelProperty(value = "状态") - private Integer status; + private String status; /** * 派单时间 @@ -60,15 +62,9 @@ public class ServiceWorkOrdersInfoVo implements Serializable { private Date dispatchTime; /** - * 发起人姓名 + * 发起人 */ - @ExcelProperty(value = "发起人姓名") - private String initiatorName; - /** - * 发起人姓名文本 - */ - @ExcelProperty(value = "发起人姓名文本") - private String initiatorNameText; + private String initiatorPeople; /** * 发起人手机号 @@ -80,7 +76,7 @@ public class ServiceWorkOrdersInfoVo implements Serializable { * 处理人姓名 */ @ExcelProperty(value = "处理人姓名") - private String handler; + private Long handler; /** * 处理人姓名文本 */ @@ -120,7 +116,7 @@ public class ServiceWorkOrdersInfoVo implements Serializable { * 是否超时 */ @ExcelProperty(value = "是否超时") - private Integer isTimeOut; + private String isTimeOut; /** * 类型名称 */ @@ -131,4 +127,10 @@ public class ServiceWorkOrdersInfoVo implements Serializable { */ @ExcelProperty(value = "创建时间") private Date createTime; + /** + *工单记录 + */ + private List workOrdersRecordVoList; + + } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrdersRecordInfoVo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrdersRecordInfoVo.java new file mode 100644 index 00000000..2a3b1b79 --- /dev/null +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrdersRecordInfoVo.java @@ -0,0 +1,59 @@ +package org.dromara.property.domain.vo; + +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import org.dromara.property.domain.ServiceWorkOrdersRecord; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + + +/** + * 工单接单记录视图对象 service_work_orders_record + * + * @author mocheng + * @date 2025-07-21 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = ServiceWorkOrdersRecord.class) +public class ServiceWorkOrdersRecordInfoVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * id + */ + @ExcelProperty(value = "id") + private Long id; + + /** + * 状态(0创建工单,1已派单2已抢单3处理中,4已完成) + */ + @ExcelProperty(value = "状态(0创建工单,1已派单2已抢单3处理中,4已完成)") + private String status; + + /** + * 处理人 + */ + @ExcelProperty(value = "处理人") + private Long handler; + /** + * 处理人 + */ + @ExcelProperty(value = "处理人") + private String handlerName; + /** + * 发起人 + */ + private String initiatorPeople; + /** + * 创建时间 + */ + @ExcelProperty(value = "创建时间") + private Date createTime; +} diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrdersRecordVo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrdersRecordVo.java new file mode 100644 index 00000000..8471f476 --- /dev/null +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrdersRecordVo.java @@ -0,0 +1,62 @@ +package org.dromara.property.domain.vo; + +import org.dromara.property.domain.ServiceWorkOrdersRecord; +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import org.dromara.common.excel.annotation.ExcelDictFormat; +import org.dromara.common.excel.convert.ExcelDictConvert; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + + + +/** + * 工单接单记录视图对象 service_work_orders_record + * + * @author mocheng + * @date 2025-07-21 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = ServiceWorkOrdersRecord.class) +public class ServiceWorkOrdersRecordVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * id + */ + @ExcelProperty(value = "id") + private Long id; + + /** + * 工单id + */ + @ExcelProperty(value = "工单id") + private String orderId; + + /** + * 状态(0创建工单,1已派单2已抢单3处理中,4已完成) + */ + @ExcelProperty(value = "状态(0创建工单,1已派单2已抢单3处理中,4已完成)") + private String status; + + /** + * 处理人 + */ + @ExcelProperty(value = "处理人") + private Long handler; + + /** + * 创建时间 + */ + @ExcelProperty(value = "创建时间") + private Date createTime; + + +} diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrdersTypeVo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrdersTypeVo.java index a590211e..b56c3c54 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrdersTypeVo.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrdersTypeVo.java @@ -68,17 +68,6 @@ public class ServiceWorkOrdersTypeVo implements Serializable { @ExcelProperty(value = "是否支持转单(0支持,1不支持)") private Integer isTransfers; - /** - * 创建人id - */ - @ExcelProperty(value = "创建人id") - private Long createById; - - /** - * 更新人id - */ - @ExcelProperty(value = "更新人id") - private Long updateById; /** * 搜索值 diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrdersVo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrdersVo.java index 163becd8..ac45e2f2 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrdersVo.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrdersVo.java @@ -59,7 +59,7 @@ public class ServiceWorkOrdersVo implements Serializable { * 状态 */ @ExcelProperty(value = "状态") - private int status; + private String status; /** * 派单时间 @@ -68,27 +68,23 @@ public class ServiceWorkOrdersVo implements Serializable { private Date dispatchTime; /** - * 发起人姓名 + * 发起人 */ - @ExcelProperty(value = "发起人姓名") - private String initiatorName; - /** - * 发起人姓名文本 - */ - @ExcelProperty(value = "发起人姓名文本") - private String initiatorNameText; + private String initiatorPeople; + /** + * 处理人姓名 + */ + private long handler; + /** + * 抄送人 + */ + private long ccPeople; /** * 发起人手机号 */ @ExcelProperty(value = "发起人手机号") private String initiatorPhone; - - /** - * 处理人姓名 - */ - @ExcelProperty(value = "处理人姓名") - private String handler; /** * 处理人姓名文本 */ @@ -124,19 +120,7 @@ public class ServiceWorkOrdersVo implements Serializable { * 是否超时 */ @ExcelProperty(value = "是否超时") - private int isTimeOut; - - /** - * 创建人id - */ - @ExcelProperty(value = "创建人id") - private Long createById; - - /** - * 更新人id - */ - @ExcelProperty(value = "更新人id") - private Long updateById; + private String isTimeOut; /** * 搜索值 diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/mapper/ServiceWorkOrdersRecordMapper.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/mapper/ServiceWorkOrdersRecordMapper.java new file mode 100644 index 00000000..6fcaff3b --- /dev/null +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/mapper/ServiceWorkOrdersRecordMapper.java @@ -0,0 +1,17 @@ +package org.dromara.property.mapper; + +import org.apache.ibatis.annotations.Mapper; +import org.dromara.property.domain.ServiceWorkOrdersRecord; +import org.dromara.property.domain.vo.ServiceWorkOrdersRecordVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 工单接单记录Mapper接口 + * + * @author mocheng + * @date 2025-07-21 + */ +@Mapper +public interface ServiceWorkOrdersRecordMapper extends BaseMapperPlus { + +} diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/ICostMeterWaterService.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/ICostMeterWaterService.java index e301107c..3370a0ce 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/ICostMeterWaterService.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/ICostMeterWaterService.java @@ -66,4 +66,10 @@ public interface ICostMeterWaterService { * @return 是否删除成功 */ Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 获取上月水电详情 + * @return + */ + CostMeterWaterVo getUltimoWater(Long roomId); } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/IServiceWorkOrdersService.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/IServiceWorkOrdersService.java index 08d66aef..9906d476 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/IServiceWorkOrdersService.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/IServiceWorkOrdersService.java @@ -3,6 +3,7 @@ package org.dromara.property.service; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.property.domain.bo.ServiceWorkOrdersBo; +import org.dromara.property.domain.vo.ServeceCustomerCountVo; import org.dromara.property.domain.vo.ServiceWorkOrdersInfoVo; import org.dromara.property.domain.vo.ServiceWorkOrdersVo; @@ -66,4 +67,10 @@ public interface IServiceWorkOrdersService { * @return 是否删除成功 */ Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 工单服务看板 + * @return + */ + ServeceCustomerCountVo counts(); } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/CostCarChargeServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/CostCarChargeServiceImpl.java index 731f8e7a..b775aa92 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/CostCarChargeServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/CostCarChargeServiceImpl.java @@ -119,6 +119,7 @@ public class CostCarChargeServiceImpl implements ICostCarChargeService { CostItemsVo costItemsVo = costItemsMapper.selectVoById(add.getCostItemsId()); BigDecimal unitPrice = costItemsVo.getUnitPrice(); add.setAmountReceivable(unitPrice); + add.setChargeStatus(ChargeStatusEnum.PAYMENT_IS_SUBJECT_TO_REVIEW.getValue()); validEntityBeforeSave(add); boolean flag = baseMapper.insert(add) > 0; if (flag) { diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/CostMeterWaterServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/CostMeterWaterServiceImpl.java index c8f8dcb1..777b0a06 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/CostMeterWaterServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/CostMeterWaterServiceImpl.java @@ -1,5 +1,6 @@ package org.dromara.property.service.impl; +import cn.hutool.core.bean.BeanUtil; import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.mybatis.core.page.TableDataInfo; @@ -136,4 +137,18 @@ public class CostMeterWaterServiceImpl implements ICostMeterWaterService { } return baseMapper.deleteByIds(ids) > 0; } + + /** + * 获取上月水电详情 + * @return + */ + @Override + public CostMeterWaterVo getUltimoWater(Long roomId) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(CostMeterWater::getRoomId, roomId); + wrapper.orderByDesc(CostMeterWater::getCreateTime); + wrapper.last("LIMIT 1"); + CostMeterWater latestRecord = baseMapper.selectOne(wrapper); + return BeanUtil.copyProperties(latestRecord,CostMeterWaterVo.class); + } } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ResidentPersonServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ResidentPersonServiceImpl.java index c37d0989..7a4668e9 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ResidentPersonServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ResidentPersonServiceImpl.java @@ -1,5 +1,6 @@ package org.dromara.property.service.impl; +import cn.hutool.core.lang.Assert; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.StringUtils; @@ -115,15 +116,23 @@ public class ResidentPersonServiceImpl implements IResidentPersonService { @Override public Boolean updateByBo(ResidentPersonBo bo) { ResidentPerson update = MapstructUtils.convert(bo, ResidentPerson.class); - validEntityBeforeSave(update); + validEntityBeforeUpdate(update); return baseMapper.updateById(update) > 0; } + /** + * 保存前的数据校验 + */ + private void validEntityBeforeUpdate(ResidentPerson entity){ + //TODO 做一些数据校验,如唯一约束 + } /** * 保存前的数据校验 */ private void validEntityBeforeSave(ResidentPerson entity){ //TODO 做一些数据校验,如唯一约束 + boolean exists = baseMapper.exists(new LambdaQueryWrapper().eq(ResidentPerson::getUserId, entity.getUserId())); + Assert.isTrue(!exists,"该用户已入住!"); } /** diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java index 866ef1d5..de1569f5 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java @@ -1,9 +1,12 @@ package org.dromara.property.service.impl; import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; +import cn.idev.excel.event.Order; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.RequiredArgsConstructor; @@ -12,14 +15,19 @@ import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.satoken.utils.LoginHelper; +import org.dromara.property.domain.ResidentPerson; import org.dromara.property.domain.ServiceWorkOrders; +import org.dromara.property.domain.ServiceWorkOrdersRecord; import org.dromara.property.domain.ServiceWorkOrdersType; import org.dromara.property.domain.bo.ServiceWorkOrdersBo; import org.dromara.property.domain.vo.*; import org.dromara.property.mapper.ResidentPersonMapper; import org.dromara.property.mapper.ServiceWorkOrdersMapper; +import org.dromara.property.mapper.ServiceWorkOrdersRecordMapper; import org.dromara.property.mapper.ServiceWorkOrdersTypeMapper; import org.dromara.property.service.IServiceWorkOrdersService; +import org.dromara.system.api.model.LoginUser; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -40,6 +48,7 @@ public class ServiceWorkOrdersServiceImpl implements IServiceWorkOrdersService { private final ServiceWorkOrdersMapper baseMapper; private final ServiceWorkOrdersTypeMapper typesMapper; private final ResidentPersonMapper residentPersonMapper; + private final ServiceWorkOrdersRecordMapper workOrdersRecordMapper; /** * 查询【工单处理】 @@ -51,20 +60,36 @@ public class ServiceWorkOrdersServiceImpl implements IServiceWorkOrdersService { public ServiceWorkOrdersInfoVo queryById(Long id) { ServiceWorkOrdersVo serviceWorkOrdersVo = baseMapper.selectVoById(id); ServiceWorkOrdersInfoVo serviceWorkOrdersInfoVo = BeanUtil.copyProperties(serviceWorkOrdersVo, ServiceWorkOrdersInfoVo.class); + if(Objects.isNull(serviceWorkOrdersInfoVo)){ + return serviceWorkOrdersInfoVo; + } ServiceWorkOrdersTypeVo serviceWorkOrdersTypeVo = typesMapper.selectVoById(serviceWorkOrdersVo.getType()); if (Objects.nonNull(serviceWorkOrdersTypeVo)) { serviceWorkOrdersInfoVo.setTypeName(serviceWorkOrdersTypeVo.getOrderTypeName()); } - ResidentPersonVo residentPersonVo = residentPersonMapper.selectVoById(Long.valueOf(serviceWorkOrdersVo.getInitiatorName())); - if (Objects.nonNull(residentPersonVo)) { - serviceWorkOrdersInfoVo.setInitiatorNameText(residentPersonVo.getUserName()); - serviceWorkOrdersInfoVo.setInitiatorPhone(residentPersonVo.getPhone()); - } ResidentPersonVo residentPersonHandler = residentPersonMapper.selectVoById(Long.valueOf(serviceWorkOrdersVo.getHandler())); if (Objects.nonNull(residentPersonHandler)) { serviceWorkOrdersInfoVo.setHandlerText(residentPersonHandler.getUserName()); serviceWorkOrdersInfoVo.setHandlerPhone(residentPersonHandler.getPhone()); } + //查询工单处理记录 + List serviceWorkOrdersRecordVoList = workOrdersRecordMapper.selectVoList(new LambdaQueryWrapper().eq(ServiceWorkOrdersRecord::getOrderId, id)); + if (CollUtil.isNotEmpty(serviceWorkOrdersRecordVoList)) { + List serviceWorkOrdersRecordInfoVos = BeanUtil.copyToList(serviceWorkOrdersRecordVoList, ServiceWorkOrdersRecordInfoVo.class); + List residentPersonIdList = serviceWorkOrdersRecordInfoVos.stream().map(vo -> vo.getHandler()).distinct().collect(Collectors.toList()); + List residentPeople = residentPersonMapper.selectByIds(residentPersonIdList); + serviceWorkOrdersRecordInfoVos.stream().forEach(workOrdersRecordVo -> { + ResidentPerson residentPerson = residentPeople.stream().filter(vo -> vo.getId() != null && vo.getId().equals(serviceWorkOrdersVo.getHandler())).findFirst().orElse(null); + workOrdersRecordVo.setHandlerName(Objects.nonNull(residentPerson) ? residentPerson.getUserName() : null); + if (Objects.nonNull(serviceWorkOrdersTypeVo)) { + workOrdersRecordVo.setInitiatorPeople(serviceWorkOrdersVo.getInitiatorPeople()); + } + if(workOrdersRecordVo.getStatus().equals("1")||workOrdersRecordVo.getStatus().equals("2")){ + serviceWorkOrdersInfoVo.setDispatchTime(workOrdersRecordVo.getCreateTime()); + } + }); + serviceWorkOrdersInfoVo.setWorkOrdersRecordVoList(serviceWorkOrdersRecordInfoVos); + } return serviceWorkOrdersInfoVo; } @@ -82,16 +107,16 @@ public class ServiceWorkOrdersServiceImpl implements IServiceWorkOrdersService { if (ObjectUtil.isEmpty(result.getRecords())) { return TableDataInfo.build(result); } - List typeList = result.getRecords().stream() - .map(vo -> vo.getType()) - .distinct() - .collect(Collectors.toList()); + List typeList = result.getRecords().stream().map(vo -> vo.getType()).distinct().collect(Collectors.toList()); List serviceWorkOrdersTypeVoList = typesMapper.selectVoByIds(typeList); + if (ObjectUtil.isEmpty(serviceWorkOrdersTypeVoList)) { + return TableDataInfo.build(result); + } List serviceWorkOrdersVoList = new ArrayList<>(); result.getRecords().stream().forEach(s -> { - ServiceWorkOrdersTypeVo serviceWorkOrdersTypeVo = serviceWorkOrdersTypeVoList.stream() - .filter(vo -> vo.getId() != null && vo.getId().equals(s.getType())).findFirst().orElse(null); - s.setTypeName(serviceWorkOrdersTypeVo.getOrderTypeName()); + ServiceWorkOrdersTypeVo serviceWorkOrdersTypeVo = serviceWorkOrdersTypeVoList.stream().filter(vo -> vo.getId() != null && vo.getId().equals(s.getType())).findFirst().orElse(null); + + s.setTypeName(ObjectUtil.isNotNull(serviceWorkOrdersTypeVo) ? serviceWorkOrdersTypeVo.getOrderTypeName() : null); serviceWorkOrdersVoList.add(s); }); return TableDataInfo.build(new Page().setRecords(serviceWorkOrdersVoList)); @@ -116,8 +141,8 @@ public class ServiceWorkOrdersServiceImpl implements IServiceWorkOrdersService { lqw.eq(StringUtils.isNotBlank(bo.getOrderNo()), ServiceWorkOrders::getOrderNo, bo.getOrderNo()); lqw.like(StringUtils.isNotBlank(bo.getOrderName()), ServiceWorkOrders::getOrderName, bo.getOrderName()); lqw.eq(bo.getDispatchTime() != null, ServiceWorkOrders::getDispatchTime, bo.getDispatchTime()); - lqw.like(StringUtils.isNotBlank(bo.getInitiatorName()), ServiceWorkOrders::getInitiatorName, bo.getInitiatorName()); - lqw.eq(StringUtils.isNotBlank(bo.getHandler()), ServiceWorkOrders::getHandler, bo.getHandler()); + lqw.like(StringUtils.isNotBlank(bo.getInitiatorName()), ServiceWorkOrders::getInitiatorPeople, bo.getInitiatorName()); + lqw.eq(ObjectUtil.isNotEmpty(bo.getHandler()), ServiceWorkOrders::getHandler, bo.getHandler()); lqw.eq(StringUtils.isNotBlank(bo.getLocation()), ServiceWorkOrders::getLocation, bo.getLocation()); lqw.eq(bo.getPlanCompleTime() != null, ServiceWorkOrders::getPlanCompleTime, bo.getPlanCompleTime()); lqw.eq(bo.getCompleTime() != null, ServiceWorkOrders::getCompleTime, bo.getCompleTime()); @@ -137,11 +162,19 @@ public class ServiceWorkOrdersServiceImpl implements IServiceWorkOrdersService { @Transactional(rollbackFor = Exception.class) public Boolean insertByBo(ServiceWorkOrdersBo bo) { ServiceWorkOrders add = MapstructUtils.convert(bo, ServiceWorkOrders.class); + LoginUser user = LoginHelper.getLoginUser(); add.setOrderNo("GD" + IdUtil.getSnowflakeNextIdStr()); + add.setStatus("0"); + add.setInitiatorPeople(user.getNickname()); validEntityBeforeSave(add); boolean flag = baseMapper.insert(add) > 0; if (flag) { bo.setId(add.getId()); + ServiceWorkOrdersRecord serviceWorkOrdersRecord = new ServiceWorkOrdersRecord(); + serviceWorkOrdersRecord.setOrderId(add.getId()); + serviceWorkOrdersRecord.setStatus(add.getStatus()); + serviceWorkOrdersRecord.setHandler(add.getHandler()); + workOrdersRecordMapper.insert(serviceWorkOrdersRecord); } return flag; } @@ -156,7 +189,7 @@ public class ServiceWorkOrdersServiceImpl implements IServiceWorkOrdersService { @Transactional(rollbackFor = Exception.class) public Boolean updateByBo(ServiceWorkOrdersBo bo) { ServiceWorkOrders update = MapstructUtils.convert(bo, ServiceWorkOrders.class); - validEntityBeforeSave(update); + validEntityBeforeUpdate(update); return baseMapper.updateById(update) > 0; } @@ -166,6 +199,25 @@ public class ServiceWorkOrdersServiceImpl implements IServiceWorkOrdersService { private void validEntityBeforeSave(ServiceWorkOrders entity) { //TODO 做一些数据校验,如唯一约束 + + } + + /** + * 修改前的数据校验 + */ + private void validEntityBeforeUpdate(ServiceWorkOrders entity) { + LambdaQueryWrapper ordersLambdaQueryWrapper = new LambdaQueryWrapper<>(); + ordersLambdaQueryWrapper.eq(ServiceWorkOrdersRecord::getOrderId, entity.getId()); + ordersLambdaQueryWrapper.eq(ServiceWorkOrdersRecord::getStatus, entity.getStatus()); + boolean exists = workOrdersRecordMapper.exists(ordersLambdaQueryWrapper); + //TODO 做一些数据校验,如唯一约束 + if (!exists) { + ServiceWorkOrdersRecord serviceWorkOrdersRecord = new ServiceWorkOrdersRecord(); + serviceWorkOrdersRecord.setOrderId(entity.getId()); + serviceWorkOrdersRecord.setStatus(entity.getStatus()); + serviceWorkOrdersRecord.setHandler(entity.getHandler()); + workOrdersRecordMapper.insert(serviceWorkOrdersRecord); + } } /** @@ -183,4 +235,40 @@ public class ServiceWorkOrdersServiceImpl implements IServiceWorkOrdersService { } return baseMapper.deleteByIds(ids) > 0; } + + /** + * 工单服务看板 + * @return + */ + @Override + public ServeceCustomerCountVo counts() { + List serviceWorkOrdersList = baseMapper.selectList(new QueryWrapper<>()); + // 总工单数 + int workOrdersTotal = serviceWorkOrdersList.size(); + + // 待派送工单 + int notWorkOrdersTotal = (int) serviceWorkOrdersList.stream().filter(order -> "0".equals(order.getStatus())).count(); + //未半结超时工单 + int novertimeOrdersTotal = (int) serviceWorkOrdersList.stream().filter(order -> !"4".equals(order.getStatus()) && "1".equals(order.getIsTimeOut())).count(); + // 处理中工单 + int inHandOrdersTotal = (int) serviceWorkOrdersList.stream().filter(order -> "3".equals(order.getStatus())).count(); + // 当月工单超时率 + int novertimeOrdersRate = (int) serviceWorkOrdersList.stream().filter(order -> "3".equals(order.getStatus())).count(); + // 当月工单数 + int monthOrdersTotal = (int) serviceWorkOrdersList.stream().filter(order -> "3".equals(order.getStatus())).count(); + // 超时工单数 + int outTimeOrdersTotal = (int) serviceWorkOrdersList.stream().filter(order -> "3".equals(order.getStatus())).count(); + // 当月满意度 + int monthoSatisfaction = (int) serviceWorkOrdersList.stream().filter(order -> "3".equals(order.getStatus())).count(); + // 满意数 + int satisfaction = (int) serviceWorkOrdersList.stream().filter(order -> "3".equals(order.getStatus())).count(); + + new ServeceCustomerCountVo() + .setWorkOrdersTotal(workOrdersTotal) + .setNotWorkOrdersTotal(notWorkOrdersTotal) + .setNovertimeOrdersTotal(novertimeOrdersTotal) + .setInHandOrdersTotal(inHandOrdersTotal); + + return null; + } } diff --git a/ruoyi-modules/Property/src/main/resources/mapper/Property/ServiceWorkOrdersRecordMapper.xml b/ruoyi-modules/Property/src/main/resources/mapper/Property/ServiceWorkOrdersRecordMapper.xml new file mode 100644 index 00000000..d32d4771 --- /dev/null +++ b/ruoyi-modules/Property/src/main/resources/mapper/Property/ServiceWorkOrdersRecordMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/controller/zkmedia/ZKLmediaController.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/controller/zkmedia/ZKLmediaController.java index 08bfff36..2f9813eb 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/controller/zkmedia/ZKLmediaController.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/controller/zkmedia/ZKLmediaController.java @@ -3,6 +3,7 @@ package org.dromara.sis.controller.zkmedia; import cn.hutool.core.util.IdUtil; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.domain.R; +import org.dromara.sis.domain.enums.FactoryNoEnum; import org.dromara.sis.sdk.zkmedia.MediaServerUtils; import org.dromara.sis.sdk.zkmedia.ZLMediaKitService; import org.dromara.sis.sdk.zkmedia.model.AddStreamProxy; @@ -49,9 +50,9 @@ public class ZKLmediaController { proxy.setApp("realtime"); String s = IdUtil.fastSimpleUUID(); proxy.setStream(s); - if ("DS1010".equals(data.getFactoryNo())) { + if (FactoryNoEnum.HIK.getCode().equals(data.getFactoryNo())) { proxy.setUrl(String.format(HIK_REALTIME_RTSP_TEMPLATE, data.getAccount(), data.getPwd(), data.getVideoIp(), data.getVideoPort(), data.getChannelId())); - } else if ("DS1014".equals(data.getFactoryNo())) { + } else if (FactoryNoEnum.DAHUA.getCode().equals(data.getFactoryNo())) { proxy.setUrl(String.format(DAHUA_REALTIME_RTSP_TEMPLATE, data.getAccount(), data.getPwd(), data.getVideoIp(), data.getVideoPort(), data.getChannelId())); } else { throw new RuntimeException("未知的设备类型!"); diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/controller/zkmedia/ZkMediaHookController.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/controller/zkmedia/ZkMediaHookController.java new file mode 100644 index 00000000..c88a72e3 --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/controller/zkmedia/ZkMediaHookController.java @@ -0,0 +1,80 @@ +package org.dromara.sis.controller.zkmedia; + +import com.alibaba.fastjson2.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.dromara.sis.sdk.zkmedia.MediaServerUtils; +import org.dromara.sis.sdk.zkmedia.model.*; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; + +@Slf4j +@RestController +@RequestMapping("/index/hook") +public class ZkMediaHookController { + + /** + * 服务器定时上报时间,上报间隔可配置,默认10s上报一次 + */ + @ResponseBody + @PostMapping(value = "/on_server_keepalive", produces = "application/json;charset=UTF-8") + public HookResult onServerKeepalive(@RequestBody OnServerKeepaliveHookParam param) { + log.debug("ZLM心跳上报,params: {}", param); + return HookResult.SUCCESS(); + } + + /** + * rtsp/rtmp/rtp 推流鉴权事件。 + */ + @ResponseBody + @PostMapping(value = "/on_publish", produces = "application/json;charset=UTF-8") + public HookResult onPublish(@RequestBody OnPushParam param) { + log.info("rtsp/rtmp/rtp 推流鉴权,params: {}", param); + return HookResult.SUCCESS(); + } + + + /** + * 播放器鉴权事件,rtsp/rtmp/http-flv/ws-flv/hls的播放都将触发此鉴权事件。 + */ + @ResponseBody + @PostMapping(value = "/on_play", produces = "application/json;charset=UTF-8") + public HookResult onPlay(@RequestBody OnPlayHookParam param) { + Map paramMap = MediaServerUtils.urlParamToMap(param.getParams()); + // 对于播放流进行鉴权 + log.info("播放器鉴权事件,params={}", JSONObject.toJSONString(param)); + return HookResult.SUCCESS(); + } + + /** + * rtsp/rtmp流注册或注销时触发此事件;此事件对回复不敏感。 + */ + @ResponseBody + @PostMapping(value = "/on_stream_changed", produces = "application/json;charset=UTF-8") + public HookResult onStreamChanged(@RequestBody OnStreamChangedHookParam param) { + log.info("[ZLM HOOK] 流注销, {}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream()); + return HookResult.SUCCESS(); + } + + /** + * 流无人观看时事件,用户可以通过此事件选择是否关闭无人看的流。 + */ + @ResponseBody + @PostMapping(value = "/on_stream_none_reader", produces = "application/json;charset=UTF-8") + public HookResult onStreamNoneReader(@RequestBody OnStreamNoneReaderHookParam param) { + log.info("[ZLM HOOK]流无人观看:{}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream()); + // TODO 关闭无人观看的流 + return HookResult.SUCCESS().setClose(true); + } + + /** + * 流未找到事件,用户可以在此事件触发时,立即去拉流,这样可以实现按需拉流;此事件对回复不敏感。 + */ + @ResponseBody + @PostMapping(value = "/on_stream_not_found", produces = "application/json;charset=UTF-8") + public HookResult onStreamNotFound(@RequestBody OnStreamNotFoundHookParam param) { + log.info("[ZLM HOOK] 流未找到:{}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream()); + return HookResult.SUCCESS(); + } + +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/enums/FactoryNoEnum.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/enums/FactoryNoEnum.java index 48fb1d9b..fb0734e6 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/enums/FactoryNoEnum.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/enums/FactoryNoEnum.java @@ -9,7 +9,8 @@ import lombok.Getter; @Getter public enum FactoryNoEnum { - HIK("DS1013"); + HIK("DS1013"), + DAHUA("DS1014"); private final String code; diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/HikApiService.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/HikApiService.java index 099b1b0b..6b680cec 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/HikApiService.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/HikApiService.java @@ -116,6 +116,7 @@ public class HikApiService { } boolean logout = LoginService.logout(lHandel); if (logout) { + log.info("设备[{}]注销完成", deviceIp); CACHE.remove(deviceIp); } return logout; diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/HikSdkConstans.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/HikSdkConstans.java index 3b86814e..a2be010e 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/HikSdkConstans.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/HikSdkConstans.java @@ -7,4 +7,6 @@ public class HikSdkConstans { */ public static final String DEFAULT_CHANNEL = "101"; + public static final Integer DEFAULT_RTSP_PORT = 554; + } diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/ZLMediaKitServiceImpl.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/ZLMediaKitServiceImpl.java index ba519235..5f3632bd 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/ZLMediaKitServiceImpl.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/ZLMediaKitServiceImpl.java @@ -14,8 +14,13 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +/** + * ZLMediaKit流媒体服务 + * + * @author lxj + */ @Slf4j -@Service("com.parkclouds.media.service.ZLMediaKitServiceImpl") +@Service public class ZLMediaKitServiceImpl implements ZLMediaKitService { @Resource @@ -141,7 +146,7 @@ public class ZLMediaKitServiceImpl implements ZLMediaKitService { commonParams.put("force", 1); R result = HttpClientUtil.get(getRequestUrl("close_streams"), commonParams, AddStreamProxyResp.class); if (result != null) { - String s =null; + String s = null; if (result.getCode() == 0) { s = "关闭流成功"; } @@ -149,7 +154,7 @@ public class ZLMediaKitServiceImpl implements ZLMediaKitService { if (result.getCode() == -1) { s = "关闭流失败"; } - log.info("{},关闭流数量:{}",s,result.getData()); + log.info("{},关闭流数量:{}", s, result.getData()); return s; } return null; diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/AddStreamProxy.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/AddStreamProxy.java index 58351c2b..afd1c406 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/AddStreamProxy.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/AddStreamProxy.java @@ -11,7 +11,6 @@ public class AddStreamProxy { @NotBlank private String videoIp; - @NotNull private Integer videoPort; @NotBlank @@ -31,6 +30,6 @@ public class AddStreamProxy { private String endTime; - private String stream; + private String stream; } diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/ISisDeviceChannelService.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/ISisDeviceChannelService.java index f1c3b650..f8b164e4 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/ISisDeviceChannelService.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/ISisDeviceChannelService.java @@ -87,5 +87,11 @@ public interface ISisDeviceChannelService { Boolean handleHikDeviceChannel(SisDeviceManageBo bo); + /** + * 通过设备ids 删除设备通道信息 + * @param deviceIds 设备ids + * @return 返回删除数量 + */ + Integer deleteByDeviceIds(List deviceIds); } diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisDeviceChannelServiceImpl.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisDeviceChannelServiceImpl.java index c7046074..079b4225 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisDeviceChannelServiceImpl.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisDeviceChannelServiceImpl.java @@ -208,7 +208,7 @@ public class SisDeviceChannelServiceImpl implements ISisDeviceChannelService { channel.setChannelName(bo.getDeviceName()); channel.setGroupId(bo.getGroupId()); channel.setDeviceIp(bo.getDeviceIp()); - channel.setDevicePort(bo.getDevicePort()); + channel.setDevicePort(HikSdkConstans.DEFAULT_RTSP_PORT); channel.setFactoryNo(bo.getFactoryNo()); channel.setDeviceAccount(bo.getDeviceAccount()); channel.setDevicePwd(bo.getDevicePwd()); @@ -223,4 +223,11 @@ public class SisDeviceChannelServiceImpl implements ISisDeviceChannelService { } return false; } + + @Override + public Integer deleteByDeviceIds(List deviceIds) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.in(SisDeviceChannel::getDeviceId, deviceIds); + return baseMapper.delete(lqw); + } } diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisDeviceManageServiceImpl.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisDeviceManageServiceImpl.java index 8245c845..c386f461 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisDeviceManageServiceImpl.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisDeviceManageServiceImpl.java @@ -1,5 +1,6 @@ package org.dromara.sis.service.impl; +import cn.hutool.core.collection.CollUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -7,6 +8,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.domain.TreeNode; import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; @@ -15,15 +17,14 @@ import org.dromara.sis.domain.bo.SisDeviceManageBo; import org.dromara.sis.domain.enums.FactoryNoEnum; import org.dromara.sis.domain.vo.SisDeviceManageVo; import org.dromara.sis.mapper.SisDeviceManageMapper; +import org.dromara.sis.sdk.hik.HikApiService; import org.dromara.sis.service.ISisDeviceChannelService; import org.dromara.sis.service.ISisDeviceManageService; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; /** @@ -38,7 +39,7 @@ import java.util.Objects; public class SisDeviceManageServiceImpl implements ISisDeviceManageService { private final SisDeviceManageMapper baseMapper; - private final ISisDeviceChannelService hikDeviceChannelService; + private final ISisDeviceChannelService deviceChannelService; /** * 查询设备管理 @@ -60,7 +61,7 @@ public class SisDeviceManageServiceImpl implements ISisDeviceManageService { */ @Override public TableDataInfo queryPageList(SisDeviceManageBo bo, PageQuery pageQuery) { - Page result =baseMapper.selectByPage(pageQuery.build(), bo); + Page result = baseMapper.selectByPage(pageQuery.build(), bo); return TableDataInfo.build(result); } @@ -110,7 +111,7 @@ public class SisDeviceManageServiceImpl implements ISisDeviceManageService { public void handleDeviceChannelInfo(SisDeviceManageBo bo) { if (Objects.equals(bo.getFactoryNo(), FactoryNoEnum.HIK.getCode())) { - hikDeviceChannelService.handleHikDeviceChannel(bo); + deviceChannelService.handleHikDeviceChannel(bo); } } @@ -142,14 +143,49 @@ public class SisDeviceManageServiceImpl implements ISisDeviceManageService { * @param isValid 是否进行有效性校验 * @return 是否删除成功 */ + @Transactional(rollbackFor = Exception.class) @Override public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { - if (isValid) { - //TODO 做一些业务上的校验,判断是否需要校验 + // 查询需要删除的设备 + List sisDeviceManages = baseMapper.selectByIds(ids); + if (CollUtil.isEmpty(sisDeviceManages)) { + return true; } - return baseMapper.deleteByIds(ids) > 0; + int i = baseMapper.deleteByIds(ids); + boolean flag = i > 0; + if (flag) { + SisDeviceManageServiceImpl aopProxy = SpringUtils.getAopProxy(this); + aopProxy.deleteDeviceRef(sisDeviceManages); + } + return flag; } + /** + * 异步删除设备的关联关系 + */ + @Async + public void deleteDeviceRef(List sisDeviceManages) { + List deviceIds = new ArrayList<>(sisDeviceManages.size()); + Map> factoryGroup = new HashMap<>(10); + sisDeviceManages.forEach(sisDeviceManage -> { + deviceIds.add(sisDeviceManage.getId()); + factoryGroup.computeIfAbsent(sisDeviceManage.getFactoryNo(), k -> new ArrayList<>()).add(sisDeviceManage); + + }); + // 删除设备通道 + int num = deviceChannelService.deleteByDeviceIds(deviceIds); + log.info("删除设备通道完成,num={}", num); + // 设备sdk注销 + for (Map.Entry> entry : factoryGroup.entrySet()) { + if (entry.getKey().equals(FactoryNoEnum.HIK.getCode())) { + entry.getValue().forEach(item -> { + HikApiService.getInstance().loginOut(item.getDeviceIp()); + }); + } + } + } + + @Override public SisDeviceManageVo queryVoByDeviceIp(Integer deviceCode) { LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); diff --git a/ruoyi-modules/Sis/src/main/resources/application.yml b/ruoyi-modules/Sis/src/main/resources/application.yml index c2acc2b9..ed056a75 100644 --- a/ruoyi-modules/Sis/src/main/resources/application.yml +++ b/ruoyi-modules/Sis/src/main/resources/application.yml @@ -32,3 +32,5 @@ spring: - optional:nacos:application-common.yml - optional:nacos:datasource.yml - optional:nacos:${spring.application.name}.yml + + diff --git a/ruoyi-modules/pom.xml b/ruoyi-modules/pom.xml index 3e55175f..bb867d3f 100644 --- a/ruoyi-modules/pom.xml +++ b/ruoyi-modules/pom.xml @@ -15,7 +15,7 @@ ruoyi-resource ruoyi-workflow Property - Sis + ruoyi-modules