diff --git a/pom.xml b/pom.xml index 98677c70..be19fd9a 100644 --- a/pom.xml +++ b/pom.xml @@ -73,7 +73,7 @@ local - dev + dev 10.20.1.65:8848 10.20.1.65:4560 DEFAULT_GROUP diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/CustomerActivityController.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/CustomerActivityController.java new file mode 100644 index 00000000..1601f98e --- /dev/null +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/CustomerActivityController.java @@ -0,0 +1,106 @@ +package org.dromara.property.controller; + +import java.util.List; + +import lombok.RequiredArgsConstructor; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import org.dromara.common.idempotent.annotation.RepeatSubmit; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.web.core.BaseController; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.core.domain.R; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.excel.utils.ExcelUtil; +import org.dromara.property.domain.vo.CustomerActivityVo; +import org.dromara.property.domain.bo.CustomerActivityBo; +import org.dromara.property.service.ICustomerActivityService; +import org.dromara.common.mybatis.core.page.TableDataInfo; + +/** + * 客户服务-活动 + * 前端访问路由地址为:/property/activity + * + * @author yuyongle + * @date 2025-09-08 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/activity") +public class CustomerActivityController extends BaseController { + + private final ICustomerActivityService customerActivityService; + + /** + * 查询客户服务-活动列表 + */ + @SaCheckPermission("property:activity:list") + @GetMapping("/list") + public TableDataInfo list(CustomerActivityBo bo, PageQuery pageQuery) { + return customerActivityService.queryPageList(bo, pageQuery); + } + + /** + * 导出客户服务-活动列表 + */ + @SaCheckPermission("property:activity:export") + @Log(title = "客户服务-活动", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(CustomerActivityBo bo, HttpServletResponse response) { + List list = customerActivityService.queryList(bo); + ExcelUtil.exportExcel(list, "客户服务-活动", CustomerActivityVo.class, response); + } + + /** + * 获取客户服务-活动详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("property:activity:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable("id") Long id) { + return R.ok(customerActivityService.queryById(id)); + } + + /** + * 新增客户服务-活动 + */ + @SaCheckPermission("property:activity:add") + @Log(title = "客户服务-活动", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody CustomerActivityBo bo) { + return toAjax(customerActivityService.insertByBo(bo)); + } + + /** + * 修改客户服务-活动 + */ + @SaCheckPermission("property:activity:edit") + @Log(title = "客户服务-活动", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody CustomerActivityBo bo) { + return toAjax(customerActivityService.updateByBo(bo)); + } + + /** + * 删除客户服务-活动 + * + * @param ids 主键串 + */ + @SaCheckPermission("property:activity:remove") + @Log(title = "客户服务-活动", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable("ids") Long[] ids) { + return toAjax(customerActivityService.deleteWithValidByIds(List.of(ids), true)); + } +} diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/TbRoomController.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/TbRoomController.java index a1c30400..1423204b 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/TbRoomController.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/TbRoomController.java @@ -62,7 +62,7 @@ public class TbRoomController extends BaseController { * * @param id 主键 */ - @SaCheckPermission("property:room:query") + // @SaCheckPermission("property:room:query") @GetMapping("/{id}") public R getInfo(@NotNull(message = "主键不能为空") @PathVariable("id") Long id) { diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/mobile/MCustomerNoticesController.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/mobile/MCustomerNoticesController.java new file mode 100644 index 00000000..0bebd6cb --- /dev/null +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/mobile/MCustomerNoticesController.java @@ -0,0 +1,38 @@ +package org.dromara.property.controller.mobile; + + +import lombok.RequiredArgsConstructor; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.property.domain.bo.CustomerNoticesBo; +import org.dromara.property.domain.vo.CustomerNoticesVo; +import org.dromara.property.service.ICustomerNoticesService; +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 + * @version 1.0 + * @description: TODO + * @date 2025/9/8 11:15 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/mobile/notices") +public class MCustomerNoticesController { + private final ICustomerNoticesService customerNoticesService; + + /** + * 头条滚动列表 + * @param bo + * @param pageQuery + * @return + */ + @GetMapping("/todayList") + public TableDataInfo todayList(CustomerNoticesBo bo, PageQuery pageQuery) { + return customerNoticesService.todayList(bo, pageQuery); + } +} diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/CustomerActivity.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/CustomerActivity.java new file mode 100644 index 00000000..9997848e --- /dev/null +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/CustomerActivity.java @@ -0,0 +1,78 @@ +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.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serial; + +/** + * 客户服务-活动对象 customer_activity + * + * @author yuyongle + * @date 2025-09-08 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("customer_activity") +public class CustomerActivity extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @TableId(value = "id") + private Long id; + + /** + * 标题 + */ + private String title; + + /** + * 状态(1待进行2进行中3已完成) + */ + private String status; + + /** + * 活动图片 + */ + private String activityImgUrl; + + /** + * 开始时间 + */ + private Date startTime; + + /** + * 结束时间 + */ + private Date endTime; + + /** + * 活动内容 + */ + private String activityContent; + + /** + * 备注 + */ + private String remark; + + /** + * 发布人 + */ + private Long issuers; + + /** + * 搜索值 + */ + private String searchValue; + + +} diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/CustomerActivityBo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/CustomerActivityBo.java new file mode 100644 index 00000000..96447477 --- /dev/null +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/CustomerActivityBo.java @@ -0,0 +1,77 @@ +package org.dromara.property.domain.bo; + +import org.dromara.property.domain.CustomerActivity; +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.*; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; + +/** + * 客户服务-活动业务对象 customer_activity + * + * @author yuyongle + * @date 2025-09-08 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = CustomerActivity.class, reverseConvertGenerate = false) +public class CustomerActivityBo extends BaseEntity { + + /** + * 主键 + */ + @NotNull(message = "主键不能为空", groups = { EditGroup.class }) + private Long id; + + /** + * 标题 + */ + @NotBlank(message = "标题不能为空", groups = { AddGroup.class, EditGroup.class }) + private String title; + + /** + * 状态(1待进行2进行中3已完成) + */ + private String status; + + /** + * 活动图片 + */ +// @NotBlank(message = "活动图片不能为空", groups = { AddGroup.class, EditGroup.class }) + private String activityImgUrl; + + /** + * 开始时间 + */ + @NotNull(message = "开始时间不能为空", groups = { AddGroup.class, EditGroup.class }) + private Date startTime; + + /** + * 结束时间 + */ + @NotNull(message = "结束时间不能为空", groups = { AddGroup.class, EditGroup.class }) + private Date endTime; + + /** + * 活动内容 + */ + @NotBlank(message = "活动内容不能为空", groups = { AddGroup.class, EditGroup.class }) + private String activityContent; + + /** + * 备注 + */ + private String remark; + + /** + * 发布人 + */ + private Long issuers; + + +} diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/entity/resident/ResidentUnit.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/entity/resident/ResidentUnit.java index 0b5d4986..71c3bfb2 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/entity/resident/ResidentUnit.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/entity/resident/ResidentUnit.java @@ -72,7 +72,10 @@ public class ResidentUnit extends TenantEntity { * 员工人数 */ private Long number; - + /** + * 建筑面积(房间建筑面积和,平方千米) + */ + private Float area; /** * 备注 */ diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/CustomerActivityVo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/CustomerActivityVo.java new file mode 100644 index 00000000..a0347a5f --- /dev/null +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/CustomerActivityVo.java @@ -0,0 +1,93 @@ +package org.dromara.property.domain.vo; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.dromara.property.domain.CustomerActivity; +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; + + + +/** + * 客户服务-活动视图对象 customer_activity + * + * @author yuyongle + * @date 2025-09-08 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = CustomerActivity.class) +public class CustomerActivityVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @ExcelProperty(value = "主键") + private Long id; + + /** + * 标题 + */ + @ExcelProperty(value = "标题") + private String title; + + /** + * 状态(1待进行2进行中3已完成) + */ + @ExcelProperty(value = "状态(1待进行2进行中3已完成)") + private String status; + + /** + * 活动图片 + */ + @ExcelProperty(value = "活动图片") + private String activityImgUrl; + + /** + * 开始时间 + */ + @ExcelProperty(value = "开始时间") + private Date startTime; + + /** + * 结束时间 + */ + @ExcelProperty(value = "结束时间") + private Date endTime; + + /** + * 活动内容 + */ + @ExcelProperty(value = "活动内容") + private String activityContent; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + /** + * 发布人 + */ + @ExcelProperty(value = "发布人") + private Long issuers; + /** + * 发布人文本 + */ + @ExcelProperty(value = "发布人文本") + private String issuersText; + + +} diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/residentVo/ResidentUnitVo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/residentVo/ResidentUnitVo.java index e93abf8d..8509c52d 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/residentVo/ResidentUnitVo.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/residentVo/ResidentUnitVo.java @@ -91,6 +91,11 @@ public class ResidentUnitVo implements Serializable { @ExcelProperty(value = "员工人数") private Long number; + /** + * 建筑面积(房间建筑面积和,平方千米) + */ + private Float area; + /** * 备注 */ diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/mapper/CustomerActivityMapper.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/mapper/CustomerActivityMapper.java new file mode 100644 index 00000000..d97e720b --- /dev/null +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/mapper/CustomerActivityMapper.java @@ -0,0 +1,15 @@ +package org.dromara.property.mapper; + +import org.dromara.property.domain.CustomerActivity; +import org.dromara.property.domain.vo.CustomerActivityVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 客户服务-活动Mapper接口 + * + * @author yuyongle + * @date 2025-09-08 + */ +public interface CustomerActivityMapper extends BaseMapperPlus { + +} diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/ICustomerActivityService.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/ICustomerActivityService.java new file mode 100644 index 00000000..94be834f --- /dev/null +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/ICustomerActivityService.java @@ -0,0 +1,69 @@ +package org.dromara.property.service; + +import org.dromara.property.domain.CustomerActivity; +import org.dromara.property.domain.vo.CustomerActivityVo; +import org.dromara.property.domain.bo.CustomerActivityBo; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * 客户服务-活动Service接口 + * + * @author yuyongle + * @date 2025-09-08 + */ +public interface ICustomerActivityService { + + /** + * 查询客户服务-活动 + * + * @param id 主键 + * @return 客户服务-活动 + */ + CustomerActivityVo queryById(Long id); + + /** + * 分页查询客户服务-活动列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 客户服务-活动分页列表 + */ + TableDataInfo queryPageList(CustomerActivityBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的客户服务-活动列表 + * + * @param bo 查询条件 + * @return 客户服务-活动列表 + */ + List queryList(CustomerActivityBo bo); + + /** + * 新增客户服务-活动 + * + * @param bo 客户服务-活动 + * @return 是否新增成功 + */ + Boolean insertByBo(CustomerActivityBo bo); + + /** + * 修改客户服务-活动 + * + * @param bo 客户服务-活动 + * @return 是否修改成功 + */ + Boolean updateByBo(CustomerActivityBo bo); + + /** + * 校验并批量删除客户服务-活动信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/ICustomerNoticesService.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/ICustomerNoticesService.java index 0376d125..812bd787 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/ICustomerNoticesService.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/ICustomerNoticesService.java @@ -65,4 +65,13 @@ public interface ICustomerNoticesService { * @return 是否删除成功 */ Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + //APP端 + /** + * 头条滚动列表 + * @param bo + * @param pageQuery + * @return + */ + TableDataInfo todayList(CustomerNoticesBo bo, PageQuery pageQuery); } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/CustomerActivityServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/CustomerActivityServiceImpl.java new file mode 100644 index 00000000..ae554982 --- /dev/null +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/CustomerActivityServiceImpl.java @@ -0,0 +1,162 @@ +package org.dromara.property.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import org.apache.dubbo.config.annotation.DubboReference; +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.satoken.utils.LoginHelper; +import org.dromara.system.api.RemoteUserService; +import org.dromara.system.api.model.LoginUser; +import org.springframework.stereotype.Service; +import org.dromara.property.domain.bo.CustomerActivityBo; +import org.dromara.property.domain.vo.CustomerActivityVo; +import org.dromara.property.domain.CustomerActivity; +import org.dromara.property.mapper.CustomerActivityMapper; +import org.dromara.property.service.ICustomerActivityService; + +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 客户服务-活动Service业务层处理 + * + * @author yuyongle + * @date 2025-09-08 + */ +@Slf4j +@RequiredArgsConstructor +@Service +public class CustomerActivityServiceImpl implements ICustomerActivityService { + + private final CustomerActivityMapper baseMapper; + @DubboReference + private RemoteUserService remoteUserService; + + /** + * 查询客户服务-活动 + * + * @param id 主键 + * @return 客户服务-活动 + */ + @Override + public CustomerActivityVo queryById(Long id){ + CustomerActivityVo customerActivityVo = baseMapper.selectVoById(id); + String issuersText = remoteUserService.selectNicknameById(customerActivityVo.getIssuers()); + customerActivityVo.setIssuersText(issuersText); + return customerActivityVo; + } + + /** + * 分页查询客户服务-活动列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 客户服务-活动分页列表 + */ + @Override + public TableDataInfo queryPageList(CustomerActivityBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + if(CollUtil.isNotEmpty(result.getRecords())){ + result.getRecords().forEach(r -> r.setIssuersText(remoteUserService.selectNicknameById(r.getIssuers()))); + } + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的客户服务-活动列表 + * + * @param bo 查询条件 + * @return 客户服务-活动列表 + */ + @Override + public List queryList(CustomerActivityBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(CustomerActivityBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.orderByAsc(CustomerActivity::getId); + lqw.eq(StringUtils.isNotBlank(bo.getTitle()), CustomerActivity::getTitle, bo.getTitle()); + lqw.eq(StringUtils.isNotBlank(bo.getStatus()), CustomerActivity::getStatus, bo.getStatus()); + lqw.eq(bo.getStartTime() != null, CustomerActivity::getStartTime, bo.getStartTime()); + lqw.eq(bo.getEndTime() != null, CustomerActivity::getEndTime, bo.getEndTime()); + return lqw; + } + + /** + * 新增客户服务-活动 + * + * @param bo 客户服务-活动 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(CustomerActivityBo bo) { + CustomerActivity add = MapstructUtils.convert(bo, CustomerActivity.class); + validEntityBeforeSave(add); + //获取当前登录 用户 + LoginUser user = LoginHelper.getLoginUser(); + add.setIssuers(user.getUserId()); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setId(add.getId()); + } + return flag; + } + + /** + * 修改客户服务-活动 + * + * @param bo 客户服务-活动 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(CustomerActivityBo bo) { + CustomerActivity update = MapstructUtils.convert(bo, CustomerActivity.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(CustomerActivity entity){ + //TODO 做一些数据校验,如唯一约束 + //判断当前时间是否在开始时间和结束时间之间 + Date now = new Date(); + if (entity.getStartTime() != null && entity.getEndTime() != null) { + entity.setStatus( + now.before(entity.getStartTime()) ? "1" : + now.after(entity.getEndTime()) ? "3" : "2" + ); + } + } + + /** + * 校验并批量删除客户服务-活动信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } +} diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/CustomerNoticesServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/CustomerNoticesServiceImpl.java index f2ccdc1c..336e9542 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/CustomerNoticesServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/CustomerNoticesServiceImpl.java @@ -237,4 +237,15 @@ public class CustomerNoticesServiceImpl implements ICustomerNoticesService { } return baseMapper.deleteByIds(ids) > 0; } + //APP端接口 + /** + * 头条滚动列表 + * @param bo + * @param pageQuery + * @return + */ + @Override + public TableDataInfo todayList(CustomerNoticesBo bo, PageQuery pageQuery) { + return queryPageList(bo, pageQuery); + } } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/InspectionTaskDetailServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/InspectionTaskDetailServiceImpl.java index 04423e19..3ea7a95f 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/InspectionTaskDetailServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/InspectionTaskDetailServiceImpl.java @@ -250,15 +250,15 @@ public class InspectionTaskDetailServiceImpl implements IInspectionTaskDetailSer private void dataProcessing(MInspectionTaskDetailVo mInspectionTaskDetailVo, Map pointNameMap) { mInspectionTaskDetailVo.setPointName(ObjectUtil.defaultIfNull(pointNameMap.get(mInspectionTaskDetailVo.getPointId()), "未知点位")); //查询工单 - if(ObjectUtil.isNotEmpty(mInspectionTaskDetailVo.getOrderId())){ + if (ObjectUtil.isNotEmpty(mInspectionTaskDetailVo.getOrderId())) { ServiceWorkOrdersVo serviceWorkOrdersVo = serviceWorkOrdersMapper.selectVoById(mInspectionTaskDetailVo.getOrderId()); - if(ObjectUtil.isNotEmpty(serviceWorkOrdersVo)){ + if (ObjectUtil.isNotEmpty(serviceWorkOrdersVo)) { List serviceWorkOrdersRecordVos = workOrdersRecordMapper.selectVoList( new LambdaQueryWrapper<>(ServiceWorkOrdersRecord.class).eq(ServiceWorkOrdersRecord::getOrderId, serviceWorkOrdersVo.getId()) ); List mServiceWorkOrdersRecordVos = BeanUtil.copyToList(serviceWorkOrdersRecordVos, MServiceWorkOrdersRecordVo.class); serviceWorkOrdersVo.setRecordVoList(mServiceWorkOrdersRecordVos); - mInspectionTaskDetailVo.setMServiceWorkOrdersVo(ObjectUtil.isNotEmpty( serviceWorkOrdersVo)? BeanUtil.copyProperties(serviceWorkOrdersVo, MServiceWorkOrdersVo.class):null); + mInspectionTaskDetailVo.setMServiceWorkOrdersVo(ObjectUtil.isNotEmpty(serviceWorkOrdersVo) ? BeanUtil.copyProperties(serviceWorkOrdersVo, MServiceWorkOrdersVo.class) : null); } } @@ -295,7 +295,18 @@ public class InspectionTaskDetailServiceImpl implements IInspectionTaskDetailSer Assert.isTrue(planInspectionPersonIds.contains(loginUser.getUserId()), "当前签到人不在计划巡检人列表内"); bo.setActualInspectionPerson(loginUser.getUserId().toString()); InspectionTaskDetail update = MapstructUtils.convert(bo, InspectionTaskDetail.class); - return baseMapper.updateById(update) > 0; + boolean flag = baseMapper.updateById(update) > 0; + if (flag) { + + } + return flag; + } + + /** + * 新增巡检点记录 + */ + private void insertPointRecord(InspectionTaskDetail inspectionTaskDetail) { + } /** @@ -313,8 +324,10 @@ public class InspectionTaskDetailServiceImpl implements IInspectionTaskDetailSer InspectionTaskDetail update = MapstructUtils.convert(bo, InspectionTaskDetail.class); return baseMapper.updateById(update) > 0; } + /** * 巡检提报工单 + * * @param bo * @return */ @@ -327,7 +340,7 @@ public class InspectionTaskDetailServiceImpl implements IInspectionTaskDetailSer serviceWorkOrders.setReportingType(OrderReportingTypeEnum.PHONE_REPORT.getValue()); LoginUser user = LoginHelper.getLoginUser(); serviceWorkOrders.setOrderNo("GD" + IdUtil.getSnowflakeNextIdStr()); - serviceWorkOrders.setOrderName("巡检"+bo.getPointId()); + serviceWorkOrders.setOrderName("巡检" + bo.getPointId()); serviceWorkOrders.setStatus(WorkOrderStatusEnum.CREATE_ORDER.getValue()); serviceWorkOrders.setInitiatorPeople(user.getNickname()); serviceWorkOrders.setProcessingWeight(serviceWorkOrdersType.getProcessingWeight()); @@ -343,14 +356,15 @@ public class InspectionTaskDetailServiceImpl implements IInspectionTaskDetailSer boolean flags = workOrdersRecordMapper.insert(serviceWorkOrdersRecord) > 0; if (flags) { if (serviceWorkOrdersType.getOperationMode().equals(OrderTypeOperationEnum.AUTOMATE_DISPATCH.getValue())) { - handleServiceWorkOrder(serviceWorkOrders,serviceWorkOrdersType,bo); + handleServiceWorkOrder(serviceWorkOrders, serviceWorkOrdersType, bo); } } } return flag; } + //自动派单 - private void handleServiceWorkOrder(ServiceWorkOrders serviceWorkOrders,ServiceWorkOrdersType serviceWorkOrdersType,InspectionTaskDetailToOrderBo bo) { + private void handleServiceWorkOrder(ServiceWorkOrders serviceWorkOrders, ServiceWorkOrdersType serviceWorkOrdersType, InspectionTaskDetailToOrderBo bo) { LocalDate today = LocalDate.now(); // 1. 获取今日排班人员(优先查缓存,未命中则查询数据库并缓存) List attendanceUserGroups = RedisUtils.getCacheList(DateUtil.today()); @@ -361,8 +375,8 @@ public class InspectionTaskDetailServiceImpl implements IInspectionTaskDetailSer .eq(AttendanceUserGroup::getDeptId, serviceWorkOrdersType.getDeptId()) .orderByAsc(AttendanceUserGroup::getStartDate) ); - if (CollUtil.isEmpty(attendanceUserGroups)|| attendanceUserGroups.size() != attendanceUserGroupList.size()) { - attendanceUserGroups=attendanceUserGroupList; + if (CollUtil.isEmpty(attendanceUserGroups) || attendanceUserGroups.size() != attendanceUserGroupList.size()) { + attendanceUserGroups = attendanceUserGroupList; Assert.isTrue(CollUtil.isNotEmpty(attendanceUserGroups), "暂无排班人员"); // 缓存当天排班数据(假设当天不会变) RedisUtils.setCacheList(DateUtil.today(), attendanceUserGroups); 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 2afb6c2a..e54e1b34 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 @@ -586,6 +586,7 @@ public class ServiceWorkOrdersServiceImpl implements IServiceWorkOrdersService { add.setOrderName("工单名称"); add.setStatus(WorkOrderStatusEnum.CREATE_ORDER.getValue()); add.setReportingType(OrderReportingTypeEnum.PHONE_REPORT.getValue()); + add.setProcessingWeight(serviceWorkOrdersType.getProcessingWeight()); add.setInitiatorPeople(user.getNickname()); validEntityBeforeSave(add); boolean flag = baseMapper.insert(add) > 0; diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/TbRoomServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/TbRoomServiceImpl.java index c7b2de9e..77db89e3 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/TbRoomServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/TbRoomServiceImpl.java @@ -30,6 +30,7 @@ import org.springframework.stereotype.Service; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; /** * 房间信息Service业务层处理 @@ -68,10 +69,12 @@ public class TbRoomServiceImpl implements ITbRoomService { tbRoomVo.setFloorText(ObjectUtil.isNotEmpty(tbFloorVo) ? tbFloorVo.getFloorName() : null); List residentUnits = residentUnitMapper.selectList( new LambdaQueryWrapper() - .eq(ResidentUnit::getLocation, tbRoomVo.getId()) + .like(ResidentUnit::getLocation, tbRoomVo.getId()) + .orderByDesc(ResidentUnit::getCreateTime) ); if (CollUtil.isNotEmpty(residentUnits)) { - tbRoomVo.setResidentUnitText(residentUnits.get(0).getName()); + //多个yi,拼接 + tbRoomVo.setResidentUnitText(residentUnits.stream().map(ResidentUnit::getName).collect(Collectors.joining(","))); } return tbRoomVo; } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/residentImpl/ResidentUnitServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/residentImpl/ResidentUnitServiceImpl.java index b1fbf5b0..f2a2e460 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/residentImpl/ResidentUnitServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/residentImpl/ResidentUnitServiceImpl.java @@ -1,6 +1,8 @@ package org.dromara.property.service.impl.residentImpl; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.digest.BCrypt; import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.StringUtils; @@ -12,7 +14,9 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.dromara.property.domain.entity.resident.ResidentPerson; +import org.dromara.property.domain.vo.TbRoomVo; import org.dromara.property.mapper.ResidentPersonMapper; +import org.dromara.property.mapper.TbRoomMapper; import org.dromara.property.service.residentService.IResidentPersonService; import org.dromara.property.service.ITbRoomService; import org.springframework.stereotype.Service; @@ -43,6 +47,7 @@ public class ResidentUnitServiceImpl implements IResidentUnitService { private final ResidentUnitMapper baseMapper; private final ITbRoomService roomService; + private final TbRoomMapper roomMapper; private final IResidentPersonService personService; private final ResidentPersonMapper personMapper; @@ -134,6 +139,7 @@ public class ResidentUnitServiceImpl implements IResidentUnitService { if (flag) { bo.setId(add.getId()); addResidentPerson(add); + } return flag; } @@ -170,12 +176,27 @@ public class ResidentUnitServiceImpl implements IResidentUnitService { validEntityBeforeSave(update); return baseMapper.updateById(update) > 0; } - /** * 保存前的数据校验 */ private void validEntityBeforeSave(ResidentUnit entity){ //TODO 做一些数据校验,如唯一约束 + //查询入驻房间总面积 + String roomId= entity.getLocation(); + if(StrUtil.isNotEmpty(roomId)){ + //roomId转换为Long类型的list + // 完整的代码实现 + List idList = Arrays.stream(roomId.split(",")) + .map(Long::parseLong) + .collect(Collectors.toList()); + List tbRoomVos = roomMapper.selectVoByIds(idList); + if(CollUtil.isNotEmpty(tbRoomVos)){ + Float totalArea = tbRoomVos.stream() + .map(TbRoomVo::getArea) + .reduce(0.0f, Float::sum); + entity.setArea(totalArea); + } + } } /** diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterInfoServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterInfoServiceImpl.java index 4da94807..dff02dba 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterInfoServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterInfoServiceImpl.java @@ -266,17 +266,17 @@ public class TbMeterInfoServiceImpl implements ITbMeterInfoService { */ @Override public void getMeterStatus(Long meterType, Long floorId) { - // 参数校验 - if (meterType == 0L || floorId == 0L) { - heartbeatTasks.stopTask("Meter_Status_Reading"); - return; - } - // 获取当前登录用户 LoginUser user = LoginHelper.getLoginUser(); String tokenValue = StpUtil.getTokenValue(); if (user == null) { - heartbeatTasks.stopTask("Meter_Status_Reading"); + heartbeatTasks.stopTask(tokenValue); + return; + } + + // 参数校验 + if (meterType == 0L || floorId == 0L) { + heartbeatTasks.stopTask(tokenValue); return; } @@ -292,7 +292,7 @@ public class TbMeterInfoServiceImpl implements ITbMeterInfoService { // 如果没有仪表信息,直接返回 if (meterInfoVoList.isEmpty()) { - heartbeatTasks.stopTask("Meter_Status_Reading"); + heartbeatTasks.stopTask(tokenValue); jsonObject.put("readingTime", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss")); jsonObject.put("data", new ArrayList<>()); remoteMessageService.sendMessage(user.getUserId(), tokenValue, jsonObject.toString()); @@ -309,7 +309,7 @@ public class TbMeterInfoServiceImpl implements ITbMeterInfoService { } // 启动定时任务 - heartbeatTasks.startHeartbeatTask("Meter_Status_Reading", () -> { + heartbeatTasks.startHeartbeatTask(tokenValue, () -> { jsonObject.put("readingTime", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss")); List meterResults; @@ -325,7 +325,7 @@ public class TbMeterInfoServiceImpl implements ITbMeterInfoService { // 处理仪表读数和状态 processMeterResults(user, jsonObject, meterResults, meterInfoVoList, tokenValue); - }, 30000); + }, 30000,300000); } /** diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterRecordServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterRecordServiceImpl.java index 1492aaeb..5e917eab 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterRecordServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterRecordServiceImpl.java @@ -212,12 +212,8 @@ public class TbMeterRecordServiceImpl implements ITbMeterRecordService { // 设置上次读数 if (hasOldRecords) { TbMeterRecord oldRecord = oldRecordMap.get(info.getId()); - if (oldRecord != null) { - record.setPreviousReading(oldRecord.getCurrentReading()); - } else { - // 如果没有找到对应的旧记录,使用默认值 - record.setPreviousReading(record.getCurrentReading()); - } + // 如果没有找到对应的旧记录,使用默认值 + record.setPreviousReading(Objects.requireNonNullElse(oldRecord, record).getCurrentReading()); } else { record.setPreviousReading(record.getCurrentReading()); } @@ -308,7 +304,6 @@ public class TbMeterRecordServiceImpl implements ITbMeterRecordService { private Map trendMonthData(String floorId, String meterId, Long meterType, String year) { Map resultMap = new HashMap<>(); List> monthList = baseMapper.getMonthTrend(StrUtil.isBlank(floorId) ? null : Long.parseLong(floorId), StrUtil.isBlank(meterId) ? null : Long.parseLong(meterId), meterType, year); - log.info("year:{},monthList:{}", year, monthList); List monthData = new ArrayList<>(); monthList.forEach(item -> monthData.add(new String[]{item.get("month").toString(), item.get("total_consumption").toString()})); Float total = monthList.stream().map(map -> new BigDecimal(map.get("total_consumption").toString())).reduce(BigDecimal::add).orElse(BigDecimal.ZERO).floatValue(); diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/tasks/HeartbeatTasks.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/tasks/HeartbeatTasks.java index 3ea0917e..60249a4f 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/tasks/HeartbeatTasks.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/tasks/HeartbeatTasks.java @@ -15,14 +15,36 @@ public class HeartbeatTasks { private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); private final Map> tasks = new ConcurrentHashMap<>(); - public void startHeartbeatTask(String taskId, Runnable task, long intervalMs) { + public void startHeartbeatTask(String taskId, Runnable task, long intervalMs, long durationMs) { // 先停止同名任务(如果存在) stopTask(taskId); - // 创建新任务 - ScheduledFuture future = scheduler.scheduleAtFixedRate( - task, 0, intervalMs, TimeUnit.MILLISECONDS); + // 如果 durationMs 为 0,表示任务无需时间限制 + if (durationMs <= 0) { + ScheduledFuture future = scheduler.scheduleAtFixedRate( + task, + 0, + intervalMs, + TimeUnit.MILLISECONDS + ); + tasks.put(taskId, future); + return; + } + // 创建一个包装任务,带时长检查 + long startTime = System.currentTimeMillis(); + ScheduledFuture future = scheduler.scheduleAtFixedRate( + () -> { + long elapsedTime = System.currentTimeMillis() - startTime; + if (elapsedTime >= durationMs) { + stopTask(taskId); + } + task.run(); + }, + 0, + intervalMs, + TimeUnit.MILLISECONDS + ); tasks.put(taskId, future); } diff --git a/ruoyi-modules/Property/src/main/resources/mapper/Property/CustomerActivityMapper.xml b/ruoyi-modules/Property/src/main/resources/mapper/Property/CustomerActivityMapper.xml new file mode 100644 index 00000000..9d57ced4 --- /dev/null +++ b/ruoyi-modules/Property/src/main/resources/mapper/Property/CustomerActivityMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/config/HikEqpConfig.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/config/HikEqpConfig.java index f1dc9bb8..38543a8a 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/config/HikEqpConfig.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/config/HikEqpConfig.java @@ -16,4 +16,8 @@ public class HikEqpConfig { private String host; + /** + * 视频回放地址 需要以/结尾 + */ + private String playBackUrl; } diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/controller/SisAlarmEventsController.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/controller/SisAlarmEventsController.java index 0f3046ae..8640f6b4 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/controller/SisAlarmEventsController.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/controller/SisAlarmEventsController.java @@ -6,6 +6,7 @@ import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; import org.dromara.common.core.domain.R; +import org.dromara.common.core.domain.TreeNode; import org.dromara.common.core.validate.AddGroup; import org.dromara.common.core.validate.EditGroup; import org.dromara.common.excel.utils.ExcelUtil; @@ -183,4 +184,18 @@ public class SisAlarmEventsController extends BaseController { List vo = sisAlarmEventsService.queryStatistics(); return R.ok(vo); } + + /** + * 查询事件树 + * 大类 + * - 小类 + * + * @param bigType 事件大类, -1 代表查询全部 + * @return 返回事件树 + */ + @GetMapping("/query/eventType/{bigType}") + public R>> queryEventType(@PathVariable("bigType") String bigType) { + List> tree = sisAlarmEventsService.queryEventType(bigType); + return R.ok(tree); + } } 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 56368e29..8c30f954 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 @@ -2,9 +2,11 @@ package org.dromara.sis.controller.zkmedia; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.domain.R; -import org.dromara.sis.sdk.zkmedia.ZLMediaKitService; +import org.dromara.sis.sdk.hik.PlayBackBo; +import org.dromara.sis.sdk.zkmedia.MediaService; import org.dromara.sis.sdk.zkmedia.model.AddStreamProxy; import org.dromara.sis.sdk.zkmedia.model.AddStreamProxyResp; +import org.dromara.sis.sdk.zkmedia.model.SdkPlayBackResp; import org.dromara.sis.sdk.zkmedia.model.StreamPlay; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; @@ -26,7 +28,7 @@ import javax.annotation.Resource; public class ZKLmediaController { @Resource - private ZLMediaKitService zlMediaKitService; + private MediaService mediaService; /** * 创建拉流任务,返回null代表创建拉流任务失败 @@ -36,7 +38,7 @@ public class ZKLmediaController { */ @PostMapping("/realtime/add") public R addStreamProxy(@RequestBody @Validated AddStreamProxy data) { - AddStreamProxyResp addStreamProxyResp = zlMediaKitService.addStreamProxy(data); + AddStreamProxyResp addStreamProxyResp = mediaService.addStreamProxy(data); if (addStreamProxyResp != null) { return R.ok(addStreamProxyResp); } @@ -52,7 +54,7 @@ public class ZKLmediaController { */ @PostMapping("/proxy") public R addStreamProxy(@RequestBody @Validated StreamPlay streamPlay) { - AddStreamProxyResp addStreamProxyResp = zlMediaKitService.addStreamProxy(streamPlay); + AddStreamProxyResp addStreamProxyResp = mediaService.addStreamProxy(streamPlay); if (addStreamProxyResp != null) { return R.ok(addStreamProxyResp); } @@ -67,7 +69,7 @@ public class ZKLmediaController { */ @PostMapping("/FFmpeg/proxy") public R addFfmpegStreamProxy(@RequestBody @Validated AddStreamProxy data) { - AddStreamProxyResp addStreamProxyResp = zlMediaKitService.addFfmpegStreamProxy(data); + AddStreamProxyResp addStreamProxyResp = mediaService.addFfmpegStreamProxy(data); if (addStreamProxyResp != null) { return R.ok(addStreamProxyResp); } @@ -83,10 +85,16 @@ public class ZKLmediaController { */ @PostMapping("/ffmpeg/proxy") public R addFfmpegProxy(@RequestBody @Validated StreamPlay data) { - AddStreamProxyResp addStreamProxyResp = zlMediaKitService.addFfmpegStreamProxy(data); + AddStreamProxyResp addStreamProxyResp = mediaService.addFfmpegStreamProxy(data); if (addStreamProxyResp != null) { return R.ok(addStreamProxyResp); } return R.fail(); } + + @PostMapping("/sdk/plackBack") + public R playBack(@RequestBody @Validated PlayBackBo playBackBo) { + SdkPlayBackResp res = mediaService.playBack(playBackBo); + return R.ok(res); + } } diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/bo/SisAlarmEventsBo.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/bo/SisAlarmEventsBo.java index b2497060..7c264a25 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/bo/SisAlarmEventsBo.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/bo/SisAlarmEventsBo.java @@ -8,6 +8,7 @@ import org.dromara.common.core.validate.AddGroup; import org.dromara.common.core.validate.EditGroup; import org.dromara.common.mybatis.core.domain.BaseEntity; import org.dromara.sis.domain.SisAlarmEvents; +import org.springframework.format.annotation.DateTimeFormat; import java.util.Date; import java.util.List; @@ -69,6 +70,7 @@ public class SisAlarmEventsBo extends BaseEntity { * 设备告警时间 */ @NotNull(message = "设备告警时间不能为空", groups = {AddGroup.class, EditGroup.class}) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date reportTime; /** diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/mapper/SisAlarmEventsMapper.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/mapper/SisAlarmEventsMapper.java index c929b4ee..9735d7e0 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/mapper/SisAlarmEventsMapper.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/mapper/SisAlarmEventsMapper.java @@ -17,7 +17,7 @@ import java.util.List; */ public interface SisAlarmEventsMapper extends BaseMapperPlus { - List queryStatisticsCurrDay(@Param("now") Date now); + List queryStatisticsCurrDay(@Param("start") Date start, @Param("end") Date end); List queryStatistics(); diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/mapper/SisDeviceChannelMapper.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/mapper/SisDeviceChannelMapper.java index 2bc99e3d..7f7c33b9 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/mapper/SisDeviceChannelMapper.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/mapper/SisDeviceChannelMapper.java @@ -1,8 +1,9 @@ package org.dromara.sis.mapper; +import org.apache.ibatis.annotations.Param; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; import org.dromara.sis.domain.SisDeviceChannel; import org.dromara.sis.domain.vo.SisDeviceChannelVo; -import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; /** * 设备通道管理Mapper接口 @@ -12,4 +13,5 @@ import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; */ public interface SisDeviceChannelMapper extends BaseMapperPlus { + SisDeviceChannel queryChannels(@Param("deviceIp") String deviceIp, @Param("channelNo") String channelNo); } diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/runner/HikDeviceApplicationRunner.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/runner/HikDeviceApplicationRunner.java index 74217f86..12f6c9af 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/runner/HikDeviceApplicationRunner.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/runner/HikDeviceApplicationRunner.java @@ -40,7 +40,7 @@ public class HikDeviceApplicationRunner implements ApplicationRunner { // 梯控登录 // runner.hikElevatorInfoLogin(); // 网络摄像头登录 - runner.hikNetCameraLogin(); +// runner.hikNetCameraLogin(); } @Async 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 10f678d6..5d7258ae 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 @@ -26,6 +26,7 @@ public class HikApiService { private static final String LOGOUT_URI = "logout"; private static final String CHANNEL_LIST = "channel/list"; private static final String FACE_UPLOAD = "flib/add"; + private static final String PLAY_BACK = "stream/playback"; /** * 发起海康设备对接模块请求 @@ -115,7 +116,11 @@ public class HikApiService { * @return 返回上传文件名称 */ public String fdLibUpload(FlibFaceAddBo addBo) { - return request("FACE_UPLOAD", JSONObject.toJSONString(addBo), String.class); + return request(FACE_UPLOAD, JSONObject.toJSONString(addBo), String.class); + } + + public Integer playBack(PlayBackBo playBackBo) { + return request(PLAY_BACK, JSONObject.toJSONString(playBackBo), Integer.class); } } diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/PlayBackBo.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/PlayBackBo.java new file mode 100644 index 00000000..f15f5e7e --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/PlayBackBo.java @@ -0,0 +1,63 @@ +package org.dromara.sis.sdk.hik; + +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.util.Date; + +@Data +public class PlayBackBo { + + /** + * 设备ip + */ + @NotEmpty(message = "设备ip不能为null") + private String deviceIp; + + /** + * 设备端口 + */ + private short port = 554; + + /** + * 设备厂商编号 + */ + private Integer factoryNo; + + /** + * 设备访问账号 + */ + private String deviceAccount; + + /** + * 设备访问密码 + */ + private String devicePwd; + + /** + * 设备通道编码 + */ + @NotNull(message = "通道编码不能为null") + private Integer channelNo; + + /** + * 码流类型 + * 1:主码流 + * 2:辅码流 + */ + private Byte streamType = 1; + + /** + * 开始时间 + */ + @NotNull(message = "开始时间不能为null") + private Date startTime; + + /** + * 结束时间 + */ + @NotNull(message = "结束时间不能为null") + private Date endTime; + +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/smartDevices/utils/LightingUtil.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/smartDevices/utils/LightingUtil.java index 61ca06ed..d5847ae8 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/smartDevices/utils/LightingUtil.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/smartDevices/utils/LightingUtil.java @@ -9,6 +9,8 @@ import java.io.IOException; import java.net.Socket; import java.nio.ByteBuffer; import java.nio.ByteOrder; +import java.util.ArrayList; +import java.util.List; import static com.ghgande.j2mod.modbus.Modbus.WRITE_SINGLE_REGISTER; @@ -24,9 +26,8 @@ public class LightingUtil { private static final int MODBUS_PORT = 502; // 功能码03(读保持寄存器) private static final byte FUNCTION_CODE = 0x03; - // 采集寄存器范围(协议地址) - private static final int START_ADDRESS = 42; // 40043 - 40001 = 42 - private static final int REGISTER_COUNT = 4; // 40046 - 40043 + 1 = 4 + // Modbus协议一次最多读取的寄存器数量 + private static final int MAX_REGISTERS_PER_REQUEST = 63; private Socket socket; private DataInputStream input; @@ -70,78 +71,6 @@ public class LightingUtil { return header; } - /** - * 读取40043-40046寄存器数据 - * - * @return 包含4个寄存器值的int数组 - */ - public int[] readRegisters() throws IOException { - // 发送读取请求 - sendRequest(); - - // 接收并解析响应 - return parseResponse(); - } - - /** - * 构造并发送Modbus TCP请求帧 - */ - private void sendRequest() throws IOException { - // 事务ID(递增) - int currentTransactionId = transactionId++; - - // 创建请求帧(12字节) - ByteBuffer buffer = ByteBuffer.allocate(12) - .order(ByteOrder.BIG_ENDIAN); - - // Header(7字节) - buffer.putShort((short) currentTransactionId); // 事务ID - buffer.putShort((short) 0); // 协议ID(0=Modbus) - buffer.putShort((short) 6); // 长度(后续字节数) - buffer.put((byte) 1); // 单元ID - - // PDU(协议数据单元) - buffer.put(FUNCTION_CODE); // 功能码 - buffer.putShort((short) START_ADDRESS); // 起始地址 - buffer.putShort((short) REGISTER_COUNT); // 寄存器数量 - - output.write(buffer.array()); - output.flush(); - } - - /** - * 解析Modbus TCP响应 - */ - private int[] parseResponse() throws IOException { - // 读取头(7字节) - byte[] header = initParse(); - - // 读取PDU(协议数据单元) - int pduLength = ByteBuffer.wrap(header, 4, 2) - .getShort() & 0xFFFF - 1; // 减去单元ID长度 - byte[] pdu = new byte[pduLength]; - input.readFully(pdu); - - // 检查异常响应(功能码高位为1) - if ((pdu[0] & 0xFF) == (FUNCTION_CODE | 0x80)) { - throw new IOException("Modbus异常响应,错误码: " + (pdu[1] & 0xFF)); - } - - // 验证功能码和字节数 - if (pdu[0] != FUNCTION_CODE || pdu[1] != REGISTER_COUNT * 2) { - throw new IOException("无效响应格式"); - } - - // 提取寄存器数据(每个寄存器2字节) - int[] values = new int[REGISTER_COUNT]; - for (int i = 0; i < REGISTER_COUNT; i++) { - int offset = 2 + i * 2; - values[i] = ByteBuffer.wrap(pdu, offset, 2) - .order(ByteOrder.BIG_ENDIAN).getShort() & 0xFFFF; - } - return values; - } - /** * 写单个保持寄存器(功能码06) * @@ -214,5 +143,128 @@ public class LightingUtil { return true; } + /** + * 读取指定数量的开关状态 + * + * @param startAddress 起始地址(协议地址) + * @param switchCount 开关数量 + * @return 包含所有开关状态的int数组,每个元素代表一个开关的状态 + * @throws IOException 如果读取过程中发生IO错误 + */ + public int[] readSwitchStatus(int startAddress, int switchCount) throws IOException { + // 如果开关数量超过单次请求限制,分批读取 + if (switchCount > MAX_REGISTERS_PER_REQUEST) { + return readSwitchStatusBatch(startAddress, switchCount); + } + + // 发送读取请求 + sendCustomRequest(startAddress, switchCount); + + // 接收并解析响应 + return parseCustomResponse(switchCount); + } + + /** + * 分批读取大量开关状态 + */ + private int[] readSwitchStatusBatch(int startAddress, int totalSwitchCount) throws IOException { + List allValues = new ArrayList<>(); + int remaining = totalSwitchCount; + int currentAddress = startAddress; + + while (remaining > 0) { + int batchSize = Math.min(remaining, MAX_REGISTERS_PER_REQUEST); + + // 发送读取请求 + sendCustomRequest(currentAddress, batchSize); + + // 接收并解析响应 + int[] batchValues = parseCustomResponse(batchSize); + + // 添加到结果列表 + for (int value : batchValues) { + allValues.add(value); + } + + // 更新剩余数量和当前地址 + remaining -= batchSize; + currentAddress += batchSize; + + // 添加小延迟,避免请求过快 + try { + Thread.sleep(10); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new IOException("读取过程被中断", e); + } + } + + // 转换为数组返回 + int[] result = new int[allValues.size()]; + for (int i = 0; i < allValues.size(); i++) { + result[i] = allValues.get(i); + } + return result; + } + + /** + * 构造并发送自定义Modbus TCP请求帧 + */ + private void sendCustomRequest(int startAddress, int registerCount) throws IOException { + // 事务ID(递增) + int currentTransactionId = transactionId++; + + // 创建请求帧(12字节) + ByteBuffer buffer = ByteBuffer.allocate(12) + .order(ByteOrder.BIG_ENDIAN); + + // Header(7字节) + buffer.putShort((short) currentTransactionId); // 事务ID + buffer.putShort((short) 0); // 协议ID(0=Modbus) + buffer.putShort((short) 6); // 长度(后续字节数) + buffer.put((byte) 1); // 单元ID + + // PDU(协议数据单元) + buffer.put(FUNCTION_CODE); // 功能码 + buffer.putShort((short) startAddress); // 起始地址 + buffer.putShort((short) registerCount); // 寄存器数量 + + output.write(buffer.array()); + output.flush(); + } + + /** + * 解析自定义Modbus TCP响应 + */ + private int[] parseCustomResponse(int expectedRegisterCount) throws IOException { + // 读取头(7字节) + byte[] header = initParse(); + + // 读取PDU(协议数据单元) + int pduLength = ByteBuffer.wrap(header, 4, 2) + .getShort() & 0xFFFF - 1; // 减去单元ID长度 + byte[] pdu = new byte[pduLength]; + input.readFully(pdu); + + // 检查异常响应(功能码高位为1) + if ((pdu[0] & 0xFF) == (FUNCTION_CODE | 0x80)) { + throw new IOException("Modbus异常响应,错误码: " + (pdu[1] & 0xFF)); + } + + // 验证功能码和字节数 + if (pdu[0] != FUNCTION_CODE || pdu[1] != expectedRegisterCount * 2) { + throw new IOException("无效响应格式"); + } + + // 提取寄存器数据(每个寄存器2字节) + int[] values = new int[expectedRegisterCount]; + for (int i = 0; i < expectedRegisterCount; i++) { + int offset = 2 + i * 2; + values[i] = ByteBuffer.wrap(pdu, offset, 2) + .order(ByteOrder.BIG_ENDIAN).getShort() & 0xFFFF; + } + return values; + } + } diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/ZLMediaKitService.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/MediaService.java similarity index 79% rename from ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/ZLMediaKitService.java rename to ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/MediaService.java index 3e922beb..7512daf5 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/ZLMediaKitService.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/MediaService.java @@ -1,16 +1,14 @@ package org.dromara.sis.sdk.zkmedia; -import org.dromara.sis.sdk.zkmedia.model.AddStreamProxy; -import org.dromara.sis.sdk.zkmedia.model.AddStreamProxyResp; -import org.dromara.sis.sdk.zkmedia.model.StartStreamProxy; -import org.dromara.sis.sdk.zkmedia.model.StreamPlay; +import org.dromara.sis.sdk.hik.PlayBackBo; +import org.dromara.sis.sdk.zkmedia.model.*; /** * 拉流服务 * @author lxj */ -public interface ZLMediaKitService { +public interface MediaService { /** * 创建视频流拉流代理 @@ -58,4 +56,10 @@ public interface ZLMediaKitService { Boolean delFfmpegSource(String key); + /** + * 通过sdk进行视频回放 + * @param playBackBo 回放参数 + * @return 返回播放地址 + */ + SdkPlayBackResp playBack(PlayBackBo playBackBo); } 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/MediaServiceImpl.java similarity index 89% rename from ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/ZLMediaKitServiceImpl.java rename to ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/MediaServiceImpl.java index b2fd8c46..70ccf193 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/MediaServiceImpl.java @@ -4,8 +4,11 @@ import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; import lombok.extern.slf4j.Slf4j; import org.dromara.sis.api.enums.FactoryNoEnum; +import org.dromara.sis.config.HikEqpConfig; import org.dromara.sis.config.ZLMediaKitConfig; import org.dromara.sis.domain.SisDeviceChannel; +import org.dromara.sis.sdk.hik.HikApiService; +import org.dromara.sis.sdk.hik.PlayBackBo; import org.dromara.sis.sdk.zkmedia.model.*; import org.dromara.sis.service.ISisDeviceChannelService; import org.jetbrains.annotations.Nullable; @@ -22,12 +25,16 @@ import java.util.Map; */ @Slf4j @Service -public class ZLMediaKitServiceImpl implements ZLMediaKitService { +public class MediaServiceImpl implements MediaService { @Resource private ZLMediaKitConfig zlmConfig; @Resource private ISisDeviceChannelService deviceChannelService; + @Resource + private HikApiService hikApiService; + @Resource + private HikEqpConfig hikEqpConfig; // 海康实时流取流模板 private static final String HIK_REALTIME_RTSP_TEMPLATE = "rtsp://%s:%s@%s:%s/Streaming/Channels/%s"; @@ -58,7 +65,7 @@ public class ZLMediaKitServiceImpl implements ZLMediaKitService { public String getRequestUrl(String uri) { if (ZLM_REQUEST_PREFIX == null) { - synchronized (ZLMediaKitServiceImpl.class) { + synchronized (this) { if (ZLM_REQUEST_PREFIX == null) { ZLM_REQUEST_PREFIX = String.format(STREAM_REQUEST_TEMLATE, zlmConfig.getIp(), zlmConfig.getHttpPort()); } @@ -331,4 +338,31 @@ public class ZLMediaKitServiceImpl implements ZLMediaKitService { return result != null && result.getCode() == 0; } + @Override + public SdkPlayBackResp playBack(PlayBackBo playBackBo) { + // 根据设备ip + 通道编码查询通道信息 + SisDeviceChannel deviceChannel = deviceChannelService.queryByNvrIpAndChannelNo(playBackBo.getDeviceIp(), playBackBo.getChannelNo()); + // 回放默认走录像机拉流 + playBackBo.setPort((short) 8000); + playBackBo.setDeviceIp(deviceChannel.getNvrIp()); + playBackBo.setDeviceAccount(deviceChannel.getNvrAccount()); + playBackBo.setDevicePwd(deviceChannel.getNvrPwd()); + if (deviceChannel.getFactoryNo().equals(FactoryNoEnum.HIK.getCode())) { + // 海康通道编码在系统中为 通道编码 + 0 + 码流类型,所以需要去掉最后2为 + if (StrUtil.isEmpty(deviceChannel.getChannelNo())) { + throw new RuntimeException("通道配置错误。"); + } else { + String channelNo = deviceChannel.getNvrChannelNo(); + channelNo = channelNo.substring(0, channelNo.length() - 2); + playBackBo.setChannelNo(Integer.valueOf(channelNo)); + } + } + + Integer i = hikApiService.playBack(playBackBo); + SdkPlayBackResp resp = new SdkPlayBackResp(); + if (i != null && i > -1) { + resp.setWsUrl(hikEqpConfig.getPlayBackUrl() + i); + } + return resp; + } } diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/SdkPlayBackResp.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/SdkPlayBackResp.java new file mode 100644 index 00000000..f9181ff0 --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/SdkPlayBackResp.java @@ -0,0 +1,10 @@ +package org.dromara.sis.sdk.zkmedia.model; + +import lombok.Data; + +@Data +public class SdkPlayBackResp { + + private String wsUrl; + +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/ISisAlarmEventsService.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/ISisAlarmEventsService.java index 46f152e2..5b386a3e 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/ISisAlarmEventsService.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/ISisAlarmEventsService.java @@ -1,5 +1,6 @@ package org.dromara.sis.service; +import org.dromara.common.core.domain.TreeNode; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.sis.domain.SisAlarmEvents; @@ -121,5 +122,10 @@ public interface ISisAlarmEventsService { */ List queryStatistics(); - + /** + * 查询事件树 + * @param bigType 事件大类,-1 查询全部 + * @return 返回事件树 + */ + List> queryEventType(String bigType); } 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 c16df746..360dce23 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 @@ -4,7 +4,6 @@ import jakarta.validation.constraints.NotEmpty; import org.dromara.common.core.domain.TreeNode; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; -import org.dromara.sis.api.domain.RemoteSisDeviceChannel; import org.dromara.sis.domain.SisDeviceChannel; import org.dromara.sis.domain.bo.SisDeviceChannelBo; import org.dromara.sis.domain.bo.SisDeviceManageBo; @@ -140,4 +139,11 @@ public interface ISisDeviceChannelService { */ SisDeviceChannel queryChannels(@NotEmpty String deviceIp, @NotEmpty String channelNo); + /** + * 通过录像机ip和通道编码获取通道信息 + * @param deviceIp 设备ip + * @param channelNo 通道编码 + * @return 返回通道信息 + */ + SisDeviceChannel queryByNvrIpAndChannelNo(String deviceIp, Integer channelNo); } diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisAlarmEventsServiceImpl.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisAlarmEventsServiceImpl.java index 2f59f655..fe7af73d 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisAlarmEventsServiceImpl.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisAlarmEventsServiceImpl.java @@ -4,15 +4,19 @@ import cn.dev33.satoken.context.mock.SaTokenContextMockUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.date.DateField; +import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.google.common.collect.Lists; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.dubbo.config.annotation.DubboReference; +import org.dromara.common.core.domain.TreeNode; import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.core.utils.TreeUtils; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.satoken.utils.LoginHelper; @@ -37,14 +41,13 @@ import org.dromara.sis.service.ISisAlarmEventAttachmentsService; import org.dromara.sis.service.ISisAlarmEventProcessService; import org.dromara.sis.service.ISisAlarmEventsService; import org.dromara.sis.service.ISisDeviceManageService; +import org.dromara.system.api.RemoteDictService; +import org.dromara.system.api.domain.vo.RemoteDictDataVo; import org.dromara.system.api.model.LoginUser; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.List; +import java.util.*; /** * 告警Service业务层处理 @@ -66,6 +69,8 @@ public class SisAlarmEventsServiceImpl implements ISisAlarmEventsService { private RemoteFileService remoteFileService; @DubboReference private RemoteAttendanceService remoteAttendanceService; + @DubboReference + private RemoteDictService remoteDictService; /** * 查询告警 @@ -123,7 +128,11 @@ public class SisAlarmEventsServiceImpl implements ISisAlarmEventsService { lqw.like(StringUtils.isNotBlank(bo.getDeviceName()), SisAlarmEvents::getDeviceName, bo.getDeviceName()); lqw.eq(bo.getDeviceGroupId() != null, SisAlarmEvents::getDeviceGroupId, bo.getDeviceGroupId()); lqw.like(StringUtils.isNotBlank(bo.getDeviceGroupName()), SisAlarmEvents::getDeviceGroupName, bo.getDeviceGroupName()); - lqw.eq(bo.getReportTime() != null, SisAlarmEvents::getReportTime, bo.getReportTime()); + if (bo.getReportTime() != null) { + Date start = DateUtil.beginOfDay(bo.getReportTime()); + Date end = DateUtil.endOfDay(bo.getReportTime()); + lqw.between(SisAlarmEvents::getReportTime, start, end); + } return lqw; } @@ -206,7 +215,7 @@ public class SisAlarmEventsServiceImpl implements ISisAlarmEventsService { // 默认服务时间为2个小时 alarmEvents.setServBeginTime(now); alarmEvents.setServEndTime(DateUtil.offset(now, DateField.HOUR, 2)); - alarmEvents.setDescription(EventSmallTypeEnum.SMART_REPORT_ZJCR.getDesc()); + alarmEvents.setDescription(type.getDesc()); int insert = this.baseMapper.insert(alarmEvents); log.info("写入报警事件表完成,num={}", insert); @@ -354,11 +363,55 @@ public class SisAlarmEventsServiceImpl implements ISisAlarmEventsService { @Override public List queryStatisticsCurrDay() { Date now = new Date(); - return this.baseMapper.queryStatisticsCurrDay(now); + DateTime start = DateUtil.beginOfDay(now); + DateTime end = DateUtil.endOfDay(now); + return this.baseMapper.queryStatisticsCurrDay(start, end); } @Override public List queryStatistics() { return this.baseMapper.queryStatistics(); } + + @Override + public List> queryEventType(String bigType) { + // 查询事件大类 + List eventBigType = remoteDictService.selectDictDataByType("event_big_type"); + if (CollUtil.isEmpty(eventBigType)) { + return List.of(); + } + // 查询事件小类 + List eventSmallType = remoteDictService.selectDictDataByType("event_small_type"); + if (CollUtil.isEmpty(eventSmallType)) { + return List.of(); + } + List> all = new ArrayList<>(eventBigType.size() + eventSmallType.size()); + + Map> bigTypeCache = new HashMap<>(); + eventSmallType.forEach(item -> { + TreeNode node = new TreeNode<>(); + node.setCode(item.getDictValue()); + node.setParentCode("-1"); + node.setLabel(item.getDictLabel()); + node.setTitle(item.getDictLabel()); + node.setChildren(Lists.newArrayList()); + bigTypeCache.put(item.getDictValue(), node); + all.add(node); + }); + + eventBigType.forEach(item -> { + TreeNode node = new TreeNode<>(); + node.setCode(item.getDictValue()); + node.setLabel(item.getDictLabel()); + node.setTitle(item.getDictLabel()); + node.setChildren(Lists.newArrayList()); + bigTypeCache.keySet().forEach(key -> { + if (item.getDictValue().startsWith(key)) { + node.setParentCode(bigTypeCache.get(key).getCode()); + } + }); + all.add(node); + }); + return TreeUtils.build(all, bigType); + } } 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 4b05153a..354644a1 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 @@ -50,7 +50,6 @@ public class SisDeviceChannelServiceImpl implements ISisDeviceChannelService { private final HikApiService hikApiService; - /** * 查询设备通道管理 * @@ -336,10 +335,14 @@ public class SisDeviceChannelServiceImpl implements ISisDeviceChannelService { @Override public SisDeviceChannel queryChannels(String deviceIp, String channelNo) { - LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); - lqw.eq(SisDeviceChannel::getDeviceIp, deviceIp); - lqw.eq(SisDeviceChannel::getChannelNo, channelNo) - .or().eq(SisDeviceChannel::getNvrChannelNo, channelNo); + return baseMapper.queryChannels(deviceIp, channelNo); + } + + @Override + public SisDeviceChannel queryByNvrIpAndChannelNo(String deviceIp, Integer channelNo) { + LambdaUpdateWrapper lqw = new LambdaUpdateWrapper<>(); + lqw.eq(SisDeviceChannel::getNvrIp, deviceIp); + lqw.eq(SisDeviceChannel::getNvrChannelNo, channelNo); return baseMapper.selectOne(lqw); } } diff --git a/ruoyi-modules/Sis/src/main/resources/mapper/sis/SisAlarmEventsMapper.xml b/ruoyi-modules/Sis/src/main/resources/mapper/sis/SisAlarmEventsMapper.xml index 83318a47..f0579ab3 100644 --- a/ruoyi-modules/Sis/src/main/resources/mapper/sis/SisAlarmEventsMapper.xml +++ b/ruoyi-modules/Sis/src/main/resources/mapper/sis/SisAlarmEventsMapper.xml @@ -8,8 +8,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" SELECT small_type typeCode, sum(1) total FROM `sis_alarm_events` - WHERE report_time BETWEEN #{now} - AND #{now} + WHERE report_time BETWEEN #{start} + AND #{end} GROUP BY small_type + SELECT * + FROM sis_device_channel + WHERE device_ip = #{deviceIp} + AND (channel_no = #{channelNo} OR nvr_channel_no = #{channelNo}) + + + diff --git a/ruoyi-modules/ruoyi-job/src/main/java/org/dromara/job/snailjob/sis/HikDeviceCheckStateTask.java b/ruoyi-modules/ruoyi-job/src/main/java/org/dromara/job/snailjob/sis/HikDeviceCheckStateTask.java index 58c03ffe..071f1f0b 100644 --- a/ruoyi-modules/ruoyi-job/src/main/java/org/dromara/job/snailjob/sis/HikDeviceCheckStateTask.java +++ b/ruoyi-modules/ruoyi-job/src/main/java/org/dromara/job/snailjob/sis/HikDeviceCheckStateTask.java @@ -159,7 +159,7 @@ public class HikDeviceCheckStateTask { // 调用设备登录验证次设备在线 Boolean isLogin = remoteHikSdkService.deviceLogin(item); int onLineState = isLogin ? 1 : 0; - if (item.getDeviceStatus() != onLineState) { + if (Objects.equals(item.getDeviceStatus(), onLineState)) { SnailJobLog.REMOTE.info("设备[{}]在线状态变更,开始更新状态。 old={},new ={} ", item.getDeviceIp(), item.getDeviceStatus(), onLineState); item.setDeviceStatus(onLineState); Boolean result = remoteDeviceService.updateDeviceState(item);