Merge branch 'master' of http://47.109.37.87:3000/by2025/SmartParks
Some checks are pending
Gitea Actions Demo / Explore-Gitea-Actions (push) Waiting to run

This commit is contained in:
15683799673
2025-07-16 02:36:48 +08:00
129 changed files with 6411 additions and 1071 deletions

View File

@@ -116,5 +116,14 @@ public class SisAccessControlController extends BaseController {
return R.ok(sisAccessControlService.queryAcTree());
}
/**
* 同步门禁设备
*
* @return boolean
*/
@GetMapping("/sync")
public R<Boolean> sync() {
return R.ok(sisAccessControlService.syncE8());
}
}

View File

@@ -1,37 +1,35 @@
package org.dromara.sis.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.dromara.common.core.domain.TreeNode;
import org.dromara.sis.domain.SisAuthRecord;
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.excel.utils.ExcelUtil;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.web.core.BaseController;
import org.dromara.sis.domain.SisAuthRecord;
import org.dromara.sis.domain.bo.AuthLibBo;
import org.dromara.sis.domain.bo.SingleAuthRecordBo;
import org.dromara.sis.domain.bo.SisAuthRecordBo;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.sis.domain.vo.SisAuthRecordVo;
import org.dromara.sis.domain.bo.SisAuthRecordBo;
import org.dromara.sis.service.ISisAuthRecordService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import org.dromara.common.mybatis.core.page.TableDataInfo;
/**
* 授权记录
* 前端访问路由地址为:/sis/authRecord
*
* @author lsm
* @since 2025-06-28
* @since 2025-07-14
*/
@Validated
@RequiredArgsConstructor
@@ -77,25 +75,13 @@ public class SisAuthRecordController extends BaseController {
* 新增授权记录
*/
@SaCheckPermission("sis:authRecord:add")
@Log(title = "授权记录", businessType = BusinessType.INSERT)
@Log(title = "人员库授权", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping("/add")
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody SisAuthRecordBo bo) {
return toAjax(sisAuthRecordService.insertByBo(bo));
}
/**
* 新增授权记录
*/
@SaCheckPermission("sis:authRecord:add")
@Log(title = "单个人像授权", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping("/auth/single")
public R<Void> singleAuth(@Validated(AddGroup.class) @RequestBody SingleAuthRecordBo bo) {
return toAjax(sisAuthRecordService.singleAuth(bo));
}
/**
* 修改授权记录
*/
@@ -121,19 +107,22 @@ public class SisAuthRecordController extends BaseController {
}
/**
* 删除授权记录
* 查询库id授权的设备
*
* @param bo 授权信息
* @param libId 人像库id
*/
@SaCheckPermission("sis:authRecord:authLib")
@Log(title = "人员库授权", businessType = BusinessType.INSERT)
@PostMapping("/authLib")
public R<Void> authLib(@Validated @RequestBody AuthLibBo bo) {
return toAjax(sisAuthRecordService.authLib(bo));
}
@GetMapping("/authDevice/{libId}")
public R<List<SisAuthRecord>> queryAuthDevice(@PathVariable("libId") String libId) {
return R.ok(sisAuthRecordService.queryAuthDevice(libId));
}
/**
* 查询所有可授权设备
*
* @return List<TreeNode < Long>>
*/
@GetMapping("/authDevice/tree")
public R<List<TreeNode<Long>>> tree() {
return R.ok(sisAuthRecordService.authDeviceTree());
}
}

View File

@@ -0,0 +1,106 @@
package org.dromara.sis.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.sis.domain.vo.SisElevatorFloorRefVo;
import org.dromara.sis.domain.bo.SisElevatorFloorRefBo;
import org.dromara.sis.service.ISisElevatorFloorRefService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
/**
* 电梯⇄楼层关联
* 前端访问路由地址为:/sis/elevatorFloorRef
*
* @author lsm
* @since 2025-07-15
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/elevatorFloorRef")
public class SisElevatorFloorRefController extends BaseController {
private final ISisElevatorFloorRefService sisElevatorFloorRefService;
/**
* 查询电梯⇄楼层关联列表
*/
@SaCheckPermission("sis:elevatorFloorRef:list")
@GetMapping("/list")
public TableDataInfo<SisElevatorFloorRefVo> list(SisElevatorFloorRefBo bo, PageQuery pageQuery) {
return sisElevatorFloorRefService.queryPageList(bo, pageQuery);
}
/**
* 导出电梯⇄楼层关联列表
*/
@SaCheckPermission("sis:elevatorFloorRef:export")
@Log(title = "电梯⇄楼层关联", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(SisElevatorFloorRefBo bo, HttpServletResponse response) {
List<SisElevatorFloorRefVo> list = sisElevatorFloorRefService.queryList(bo);
ExcelUtil.exportExcel(list, "电梯⇄楼层关联", SisElevatorFloorRefVo.class, response);
}
/**
* 获取电梯⇄楼层关联详细信息
*
* @param id 主键
*/
@SaCheckPermission("sis:elevatorFloorRef:query")
@GetMapping("/{id}")
public R<SisElevatorFloorRefVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable("id") Long id) {
return R.ok(sisElevatorFloorRefService.queryById(id));
}
/**
* 新增电梯⇄楼层关联
*/
@SaCheckPermission("sis:elevatorFloorRef:add")
@Log(title = "电梯⇄楼层关联", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody SisElevatorFloorRefBo bo) {
return toAjax(sisElevatorFloorRefService.insertByBo(bo));
}
/**
* 修改电梯⇄楼层关联
*/
@SaCheckPermission("sis:elevatorFloorRef:edit")
@Log(title = "电梯⇄楼层关联", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody SisElevatorFloorRefBo bo) {
return toAjax(sisElevatorFloorRefService.updateByBo(bo));
}
/**
* 删除电梯⇄楼层关联
*
* @param ids 主键串
*/
@SaCheckPermission("sis:elevatorFloorRef:remove")
@Log(title = "电梯⇄楼层关联", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable("ids") Long[] ids) {
return toAjax(sisElevatorFloorRefService.deleteWithValidByIds(List.of(ids), true));
}
}

View File

@@ -0,0 +1,106 @@
package org.dromara.sis.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.sis.domain.vo.SisFloorInfoVo;
import org.dromara.sis.domain.bo.SisFloorInfoBo;
import org.dromara.sis.service.ISisFloorInfoService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
/**
* 建筑物楼层信息
* 前端访问路由地址为:/sis/floorInfo
*
* @author lsm
* @since 2025-07-15
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/floorInfo")
public class SisFloorInfoController extends BaseController {
private final ISisFloorInfoService sisFloorInfoService;
/**
* 查询建筑物楼层信息列表
*/
@SaCheckPermission("sis:floorInfo:list")
@GetMapping("/list")
public TableDataInfo<SisFloorInfoVo> list(SisFloorInfoBo bo, PageQuery pageQuery) {
return sisFloorInfoService.queryPageList(bo, pageQuery);
}
/**
* 导出建筑物楼层信息列表
*/
@SaCheckPermission("sis:floorInfo:export")
@Log(title = "建筑物楼层信息", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(SisFloorInfoBo bo, HttpServletResponse response) {
List<SisFloorInfoVo> list = sisFloorInfoService.queryList(bo);
ExcelUtil.exportExcel(list, "建筑物楼层信息", SisFloorInfoVo.class, response);
}
/**
* 获取建筑物楼层信息详细信息
*
* @param floorId 主键
*/
@SaCheckPermission("sis:floorInfo:query")
@GetMapping("/{floorId}")
public R<SisFloorInfoVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable("floorId") Long floorId) {
return R.ok(sisFloorInfoService.queryById(floorId));
}
/**
* 新增建筑物楼层信息
*/
@SaCheckPermission("sis:floorInfo:add")
@Log(title = "建筑物楼层信息", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody SisFloorInfoBo bo) {
return toAjax(sisFloorInfoService.insertByBo(bo));
}
/**
* 修改建筑物楼层信息
*/
@SaCheckPermission("sis:floorInfo:edit")
@Log(title = "建筑物楼层信息", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody SisFloorInfoBo bo) {
return toAjax(sisFloorInfoService.updateByBo(bo));
}
/**
* 删除建筑物楼层信息
*
* @param floorIds 主键串
*/
@SaCheckPermission("sis:floorInfo:remove")
@Log(title = "建筑物楼层信息", businessType = BusinessType.DELETE)
@DeleteMapping("/{floorIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable("floorIds") Long[] floorIds) {
return toAjax(sisFloorInfoService.deleteWithValidByIds(List.of(floorIds), true));
}
}

View File

@@ -98,7 +98,7 @@ public class SisPersonLibController extends BaseController {
*/
@SaCheckPermission("sis:personLib:remove")
@Log(title = "人像库", businessType = BusinessType.DELETE)
@DeleteMapping("del/{ids}")
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable("ids") Long[] ids) {
return toAjax(tbPersonLibService.deleteWithValidByIds(List.of(ids), true));

View File

@@ -1,108 +0,0 @@
package org.dromara.sis.controller.e8;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.R;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.sis.sdk.e8.AccessControlService;
import org.dromara.sis.sdk.e8.domain.QueryDto;
import org.dromara.sis.sdk.e8.domain.accessControl.req.CustomerAuthAddReq;
import org.dromara.sis.sdk.e8.domain.accessControl.req.RemoteOpenDoorReq;
import org.dromara.sis.sdk.e8.domain.accessControl.res.AccessRecordFindRes;
import org.dromara.sis.sdk.e8.domain.accessControl.res.CustomerAuthFindRes;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author lsm
* @apiNote AccessControlController
* @since 2025/6/24
*/
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/e8AccessControl")
public class AccessControlController {
private final AccessControlService accessControlService;
/**
* 远程开门
*
* @param req 传参
* @return Boolean
*/
@PostMapping("/remoteOpenDoor")
public R<Boolean> remoteOpenDoor(@RequestBody RemoteOpenDoorReq req) {
log.info("E8远程开门 入参:{}", req);
Boolean flag = accessControlService.remoteOpenDoor(req);
if (flag) {
return R.ok();
} else {
return R.fail("E8远程开门调用失败");
}
}
/**
* 获取门禁记录列表
*
* @param dto 查询参数
* @return IPage<AccessRecordFindRes>
* @apiNote 获取参数示例 {"maxResultCount":10,"pageIndex":1,"queryDto":{"isViewFullData":false}}
*/
@PostMapping("/getPageAccessRecordList")
public R<TableDataInfo<AccessRecordFindRes>> getPageAccessRecordList(@RequestBody QueryDto dto) {
log.info("E8获取门禁记录列表 入参:{}", dto);
TableDataInfo<AccessRecordFindRes> page = accessControlService.getPageAccessRecordList(dto);
if (page == null) {
return R.fail("E8获取门禁记录列表调用失败");
} else {
return R.ok(page);
}
}
/**
* 人员授权
*
* @param req 传参
* @return Boolean
* @apiNote 参数示例 {"accessAuthModel":0,"authData":[{"floors":[],"gatewayType":1,"id":528705580163141,"type":0}],"authType":0,"elevatorAuthModel":1,"endTime":"2025-07-2511: 23: 39","personIds":[539696740646981],"scheduleId":1,"startTime":"2025-06-2511: 23: 39"}
*/
@PostMapping("/addCustomerAuth")
public R<Boolean> addCustomerAuth(@RequestBody CustomerAuthAddReq req) {
log.info("E8人员授权 入参:{}", req);
Boolean flag = accessControlService.addCustomerAuth(req);
if (flag) {
return R.ok();
} else {
return R.fail("E8人员授权调用失败");
}
}
/**
* 获取人员权限分页列表
*
* @param dto 获取参数
* @return TableDataInfo<CustomerAuthFindRes>
* @apiNote 获取参数示例 {"maxResultCount":10,"pageIndex":1,"queryDto":{"isViewFullData":false}}
*/
@PostMapping("getPageCustomerAuth")
public R<TableDataInfo<CustomerAuthFindRes>> getPageCustomerAuth(@RequestBody QueryDto dto) {
log.info("E8获取人员权限分页列表 入参:{}", dto);
TableDataInfo<CustomerAuthFindRes> page = accessControlService.getPageCustomerAuth(dto);
if (page == null) {
return R.fail("E8获取人员权限分页列表调用失败");
} else {
return R.ok(page);
}
}
}

View File

@@ -1,115 +0,0 @@
package org.dromara.sis.controller.e8;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.R;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.sis.sdk.e8.DoorDeviceService;
import org.dromara.sis.sdk.e8.domain.door.req.DoorDeviceAddReq;
import org.dromara.sis.sdk.e8.domain.door.req.DoorDeviceUpdateReq;
import org.dromara.sis.sdk.e8.domain.door.res.DoorDeviceAddRes;
import org.dromara.sis.sdk.e8.domain.door.res.DoorDeviceFindRes;
import org.dromara.sis.sdk.e8.domain.QueryDto;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
/**
* @author lsm
* @apiNote DoorDeviceController
* @since 2025/6/23
*/
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/e8DoorDevice")
public class DoorDeviceController {
private final DoorDeviceService doorDeviceService;
/**
* 查询门禁信息
*
* @param id 入参
* @return Result
*/
@PostMapping("/findDoorDevice/{id}")
public R<DoorDeviceFindRes> findDoorDevice(@PathVariable Long id) {
log.info("E8接口 查询门禁信息 入参={}", id);
DoorDeviceFindRes doorDeviceInfo = doorDeviceService.findDoorDevice(id);
if (doorDeviceInfo == null) {
return R.fail("E8接口查询门禁信息调用失败");
} else {
return R.ok(doorDeviceInfo);
}
}
/**
* 新增门禁信息
*
* @param addReq 入参
* @return Boolean
*/
@PostMapping("/addDoorDevice")
public R<DoorDeviceAddRes> addDoorDevice(@RequestBody DoorDeviceAddReq addReq) {
log.info("E8接口新增门禁信息 入参={}", addReq);
DoorDeviceAddRes doorDevice = doorDeviceService.addDoorDevice(addReq);
if (doorDevice == null) {
return R.fail("E8接口新增门禁信息调用失败");
} else {
return R.ok(doorDevice);
}
}
/**
* 门禁信息修改
*
* @param updateReq 入参
* @return Boolean
*/
@PostMapping("/updateDoorDevice")
public R<Boolean> updateDoorDevice(@RequestBody DoorDeviceUpdateReq updateReq) {
log.info("E8接口门禁信息修改 入参={}", updateReq);
Boolean flag = doorDeviceService.updateDoorDevice(updateReq);
if (flag) {
return R.ok();
} else {
return R.fail("E8接口门禁信息修改调用失败");
}
}
/**
* 删除门禁信息
*
* @param id 入参
* @return Boolean
*/
@PostMapping("/deleteDoorDevice/{id}")
public R<Boolean> deleteDoorDevice(@PathVariable Long id) {
log.info("E8接口删除门禁信息 入参={}", id);
Boolean flag = doorDeviceService.deleteDoorDevice(id);
return flag ? R.ok() : R.fail("E8接口删除门禁信息调用失败");
}
/**
* 查询门禁信息列表
*
* @param dto 入参
* @return IPage<DoorDeviceFindRes>
*/
@PostMapping("/findDoorDeviceList")
public R<TableDataInfo<DoorDeviceFindRes>> findDoorDeviceList(@RequestBody QueryDto dto) {
log.info("E8接口查询门禁信息列表 入参={}", dto);
TableDataInfo<DoorDeviceFindRes> doorDeviceList = doorDeviceService.findDoorDeviceList(dto);
if (ObjectUtils.isEmpty(doorDeviceList)) {
return R.fail("E8接口查询门禁信息列表调用失败");
} else {
return R.ok(doorDeviceList);
}
}
}

View File

@@ -1,113 +0,0 @@
package org.dromara.sis.controller.e8;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.R;
import org.dromara.sis.sdk.e8.VoucherControlService;
import org.dromara.sis.sdk.e8.domain.voucher.req.ChangeCardReq;
import org.dromara.sis.sdk.e8.domain.voucher.req.IssueVoucherReq;
import org.dromara.sis.sdk.e8.domain.voucher.req.OperateVoucherReq;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
/**
* @author lsm
* @apiNote VoucherControlController
* @since 2025/6/25
*/
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/e8VoucherControl")
public class VoucherControlController {
private final VoucherControlService voucherControlService;
/**
* 发行凭证
*
* @param req 入参
* @return 是否成功
*/
@PostMapping("/issueVoucher")
public R<Boolean> issueVoucher(@RequestBody IssueVoucherReq req) {
log.info("E8发行凭证入参{}", req);
Long flag = voucherControlService.issueVoucher(req);
if (flag != null) {
return R.ok();
} else {
return R.fail("E8发行凭证调用失败");
}
}
/**
* 操作凭证
*
* @param req 入参
* @return Boolean
*/
@PostMapping("/operateVoucher")
public R<Boolean> operateVoucher(@RequestBody OperateVoucherReq req) {
log.info("E8操作凭证入参{}", req);
Boolean flag = voucherControlService.operateVoucher(req);
if (flag) {
return R.ok();
} else {
return R.fail("E8操作凭证调用失败");
}
}
/**
* 换卡补卡
*
* @param req 入参
* @return Boolean
*/
@PostMapping("/changeCard")
public R<Boolean> changeCard(@RequestBody ChangeCardReq req) {
log.info("E8换卡补卡入参{}", req);
Boolean flag = voucherControlService.changeCard(req);
if (flag) {
return R.ok();
} else {
return R.fail("E8换卡补卡调用失败");
}
}
/**
* 上传人脸
*
* @param file 入参
* @return imageUrl 人脸图片地址
*/
@PostMapping("/uploadFace")
public R<String> uploadFace(@RequestParam("file") MultipartFile file) {
log.info("E8上传人脸入参{}", file.getOriginalFilename());
// 获取文件字节数组
byte[] imageByte;
try {
imageByte = file.getBytes();
} catch (IOException e) {
log.error("获取上传文件字节失败:{}", e.getMessage());
return R.fail("E8上传人脸获取文件字节失败");
}
String imageUrl = voucherControlService.uploadFace(imageByte);
if (imageUrl != null) {
return R.ok(imageUrl);
} else {
return R.fail("E8上传人脸调用失败");
}
}
}

View File

@@ -93,4 +93,9 @@ public class SisAccessControl extends TenantEntity {
*/
private String outCode;
/**
* 外部门编码
*/
private String outDoorCode;
}

View File

@@ -11,7 +11,7 @@ import java.io.Serial;
* 授权记录对象 sis_auth_record
*
* @author lsm
* @since 2025-06-28
* @since 2025-07-14
*/
@Data
@EqualsAndHashCode(callSuper = true)
@@ -33,29 +33,14 @@ public class SisAuthRecord extends TenantEntity {
private Long libId;
/**
* 图片id
*/
private Long imgId;
/**
* 门禁id
*/
private Long acId;
/**
* 设备id
*/
private Long eqbId;
/*
门id
*/
private Long doorId;
/**
* 设备id
* 设备id门禁/电梯)
*/
private Long deviceId;
/**
* 设备类型1-门禁 2-电梯
*/
private Integer deviceType;
}

View File

@@ -0,0 +1,41 @@
package org.dromara.sis.domain;
import org.dromara.common.tenant.core.TenantEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serial;
/**
* 电梯⇄楼层关联对象 sis_elevator_floor_ref
*
* @author lsm
* @since 2025-07-15
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("sis_elevator_floor_ref")
public class SisElevatorFloorRef extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
@TableId(value = "id")
private Long id;
/**
* 电梯id
*/
private Long elevatorId;
/**
* 楼层层数
*/
private Long layerNum;
}

View File

@@ -0,0 +1,50 @@
package org.dromara.sis.domain;
import org.dromara.common.tenant.core.TenantEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serial;
/**
* 建筑物楼层信息对象 sis_floor_info
*
* @author lsm
* @since 2025-07-15
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("sis_floor_info")
public class SisFloorInfo extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 楼层唯一标识
*/
@TableId(value = "floor_id")
private Long floorId;
/**
* 最低层
*/
private Long minLayer;
/**
* 最高层
*/
private Long maxLayer;
/**
* 园区id
*/
private Long communityId;
/**
* 建筑id
*/
private Long buildingId;
}

View File

@@ -0,0 +1,42 @@
package org.dromara.sis.domain;
import org.dromara.common.tenant.core.TenantEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serial;
/**
* 人像库-人像图片关联对象 sis_lib_img_ref
*
* @author lsm
* @since 2025-07-14
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("sis_lib_img_ref")
public class SisLibImgRef extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(value = "id")
private Long id;
/**
* 人像库id
*/
private Long libId;
/**
* 人像id
*/
private Long imgId;
}

View File

@@ -28,11 +28,6 @@ public class SisPersonLibImg extends TenantEntity {
@TableId(value = "id")
private Long id;
/**
* 人员库编码
*/
private Long libId;
/**
* 人像名称
*/

View File

@@ -1,22 +0,0 @@
package org.dromara.sis.domain.bo;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.List;
/**
* 人像库授权
*
* @author lxj
*/
@Data
public class AuthLibBo {
@NotNull(message = "人像库id不能为空")
private Long libId;
@NotNull(message = "设备列表不能为空")
private List<Long> deviceIds;
}

View File

@@ -1,44 +0,0 @@
package org.dromara.sis.domain.bo;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
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.SisAuthRecord;
import java.util.List;
/**
* 授权记录业务对象 sis_auth_record
*
* @author lxj
* @since 2025-06-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = SisAuthRecord.class, reverseConvertGenerate = false)
public class SingleAuthRecordBo extends BaseEntity {
/**
* 图像库Id
*/
@NotNull(message = "图像库Id不能为空", groups = {AddGroup.class, EditGroup.class})
private Long libId;
/**
* 图像id列表
*/
@NotNull(message = "图像id列表不能为空", groups = {AddGroup.class, EditGroup.class})
private Long imgId;
/**
* 门禁id列表
*/
@NotNull(message = "门禁id列表能为空", groups = {AddGroup.class, EditGroup.class})
private List<Long> acIds;
}

View File

@@ -1,21 +1,21 @@
package org.dromara.sis.domain.bo;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.sis.domain.SisAuthRecord;
import org.dromara.common.mybatis.core.domain.BaseEntity;
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.SisAuthRecord;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
import java.util.List;
import java.util.Collection;
/**
* 授权记录业务对象 sis_auth_record
*
* @author lsm
* @since 2025-06-28
* @since 2025-07-14
*/
@Data
@EqualsAndHashCode(callSuper = true)
@@ -23,26 +23,20 @@ import java.util.List;
public class SisAuthRecordBo extends BaseEntity {
/**
* 图像库Id
* 主键id
*/
@NotNull(message = "图像库Id不能为空", groups = {AddGroup.class, EditGroup.class})
@NotNull(message = "主键id不能为空", groups = {EditGroup.class})
private Long id;
/**
* 图像库id
*/
@NotNull(message = "图像库id不能为空", groups = {AddGroup.class, EditGroup.class})
private Long libId;
/**
* 图像id列表
* 授权设备idList
*/
@NotNull(message = "图像id列表不能为空", groups = {AddGroup.class, EditGroup.class})
private List<Long> imgIds;
/**
* 门禁id列表
*/
@NotNull(message = "门禁id列表能为空", groups = {AddGroup.class, EditGroup.class})
private List<Long> acIds;
/**
* 是否将图片下发到宇视盒子
*/
private Boolean issue = false;
@NotEmpty(message = "授权设备idList不能为空", groups = {AddGroup.class, EditGroup.class})
private Collection<Long> deviceIds;
}

View File

@@ -0,0 +1,42 @@
package org.dromara.sis.domain.bo;
import org.dromara.sis.domain.SisElevatorFloorRef;
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.*;
/**
* 电梯⇄楼层关联业务对象 sis_elevator_floor_ref
*
* @author lsm
* @since 2025-07-15
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = SisElevatorFloorRef.class, reverseConvertGenerate = false)
public class SisElevatorFloorRefBo extends BaseEntity {
/**
* 主键id
*/
@NotNull(message = "主键id不能为空", groups = { EditGroup.class })
private Long id;
/**
* 电梯id
*/
@NotNull(message = "电梯id不能为空", groups = { AddGroup.class, EditGroup.class })
private Long elevatorId;
/**
* 楼层层数
*/
@NotNull(message = "楼层层数不能为空", groups = { AddGroup.class, EditGroup.class })
private Long layerNum;
}

View File

@@ -0,0 +1,53 @@
package org.dromara.sis.domain.bo;
import org.dromara.sis.domain.SisFloorInfo;
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.*;
/**
* 建筑物楼层信息业务对象 sis_floor_info
*
* @author lsm
* @since 2025-07-15
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = SisFloorInfo.class, reverseConvertGenerate = false)
public class SisFloorInfoBo extends BaseEntity {
/**
* 楼层唯一标识
*/
@NotNull(message = "楼层唯一标识不能为空", groups = { EditGroup.class })
private Long floorId;
/**
* 最低层
*/
@NotNull(message = "最低层不能为空", groups = { AddGroup.class, EditGroup.class })
private Long minLayer;
/**
* 最高层
*/
@NotNull(message = "最高层不能为空", groups = { AddGroup.class, EditGroup.class })
private Long maxLayer;
/**
* 园区id
*/
@NotNull(message = "园区id不能为空", groups = { AddGroup.class, EditGroup.class })
private Long communityId;
/**
* 建筑id
*/
@NotNull(message = "建筑id不能为空", groups = { AddGroup.class, EditGroup.class })
private Long buildingId;
}

View File

@@ -0,0 +1,42 @@
package org.dromara.sis.domain.bo;
import org.dromara.sis.domain.SisLibImgRef;
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.*;
/**
* 人像库-人像图片关联业务对象 sis_lib_img_ref
*
* @author lsm
* @since 2025-07-14
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = SisLibImgRef.class, reverseConvertGenerate = false)
public class SisLibImgRefBo extends BaseEntity {
/**
* 主键id
*/
@NotNull(message = "主键id不能为空", groups = { EditGroup.class })
private Long id;
/**
* 人像库id
*/
@NotNull(message = "人像库id不能为空", groups = {EditGroup.class, AddGroup.class})
private Long libId;
/**
* 人像id
*/
@NotNull(message = "人像id不能为空", groups = {EditGroup.class, AddGroup.class})
private Long imgId;
}

View File

@@ -9,6 +9,8 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
import java.util.Collection;
/**
* 人像信息业务对象 tb_person_lib_img
*
@@ -29,8 +31,8 @@ public class SisPersonLibImgBo extends BaseEntity {
/**
* 人员库编码
*/
@NotNull(message = "人像库id不能为空", groups = {AddGroup.class, EditGroup.class})
private Long libId;
@NotEmpty(message = "人像库id不能为空", groups = {AddGroup.class, EditGroup.class})
private Collection<Long> libIds;
/**
* 人像名称
@@ -74,14 +76,14 @@ public class SisPersonLibImgBo extends BaseEntity {
*/
private String birthDate;
/**
* 同步E8
*/
private Boolean isSyncE8;
/**
* 远程库图像ID
*/
private Long remoteImgId;
/**
* 同步E8
*/
private Boolean isSyncE8;
}

View File

@@ -105,6 +105,12 @@ public class SisAccessControlVo implements Serializable {
@ExcelProperty(value = "外部编码")
private String outCode;
/**
* 外部门编码
*/
@ExcelProperty(value = "外部编码")
private String outDoorCode;
private String bindDeviceId;
private String bindDeviceIp;

View File

@@ -3,19 +3,20 @@ package org.dromara.sis.domain.vo;
import org.dromara.sis.domain.SisAuthRecord;
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.List;
/**
* 授权记录视图对象 sis_auth_record
*
* @author lsm
* @since 2025-06-28
* @since 2025-07-14
*/
@Data
@ExcelIgnoreUnannotated
@@ -32,41 +33,23 @@ public class SisAuthRecordVo implements Serializable {
private Long id;
/**
* 图像库Id
* 图像库id
*/
@ExcelProperty(value = "图像库Id")
@ExcelProperty(value = "图像库id")
private Long libId;
/**
* 人像id
*/
@ExcelProperty(value = "人像id")
private Long imgId;
/**
* 门禁id
*/
@ExcelProperty(value = "门禁id")
private Long acId;
/**
* 设备id
*/
@ExcelProperty(value = "设备id")
private Long eqbId;
/**
* E8权限ID
*/
private Long remoteAuthId;
/*
门id
*/
private Long doorId;
/**
* 设备id
* 设备id门禁/电梯)
*/
@ExcelProperty(value = "设备id", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "门禁/电梯")
private Long deviceId;
/**
* 设备类型1-门禁 2-电梯
*/
@ExcelProperty(value = "设备类型1-门禁 2-电梯")
private Integer deviceType;
}

View File

@@ -0,0 +1,50 @@
package org.dromara.sis.domain.vo;
import org.dromara.sis.domain.SisElevatorFloorRef;
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;
/**
* 电梯⇄楼层关联视图对象 sis_elevator_floor_ref
*
* @author lsm
* @since 2025-07-15
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = SisElevatorFloorRef.class)
public class SisElevatorFloorRefVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
@ExcelProperty(value = "主键id")
private Long id;
/**
* 电梯id
*/
@ExcelProperty(value = "电梯id")
private Long elevatorId;
/**
* 楼层层数
*/
@ExcelProperty(value = "楼层层数")
private Long layerNum;
}

View File

@@ -0,0 +1,61 @@
package org.dromara.sis.domain.vo;
import org.dromara.sis.domain.SisFloorInfo;
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;
/**
* 建筑物楼层信息视图对象 sis_floor_info
*
* @author lsm
* @since 2025-07-15
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = SisFloorInfo.class)
public class SisFloorInfoVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 楼层唯一标识
*/
@ExcelProperty(value = "楼层唯一标识")
private Long floorId;
/**
* 最低层
*/
@ExcelProperty(value = "最低层")
private Long minLayer;
/**
* 最高层
*/
@ExcelProperty(value = "最高层")
private Long maxLayer;
/**
* 园区id
*/
@ExcelProperty(value = "园区id")
private Long communityId;
/**
* 建筑id
*/
@ExcelProperty(value = "建筑id")
private Long buildingId;
}

View File

@@ -0,0 +1,47 @@
package org.dromara.sis.domain.vo;
import org.dromara.sis.domain.SisLibImgRef;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 人像库-人像图片关联视图对象 sis_lib_img_ref
*
* @author lsm
* @since 2025-07-14
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = SisLibImgRef.class)
public class SisLibImgRefVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
@ExcelProperty(value = "主键id")
private Long id;
/**
* 人像库id
*/
@ExcelProperty(value = "人像库id")
private Long libId;
/**
* 人像id
*/
@ExcelProperty(value = "人像id")
private Long imgId;
}

View File

@@ -8,7 +8,7 @@ import org.dromara.sis.domain.SisPersonLibImg;
import java.io.Serial;
import java.io.Serializable;
import java.util.Collection;
/**
@@ -31,12 +31,6 @@ public class SisPersonLibImgVo implements Serializable {
@ExcelProperty(value = "主键id")
private Long id;
/**
* 人员库编码
*/
@ExcelProperty(value = "人员库Id")
private Long libId;
/**
* 人像名称
*/
@@ -50,8 +44,7 @@ public class SisPersonLibImgVo implements Serializable {
private Long imgOssId;
/**
* 性别 1
2女 99未说明
* 性别 1 2女 99未说明
*/
@ExcelProperty(value = "性别")
private Integer sex;
@@ -69,9 +62,7 @@ public class SisPersonLibImgVo implements Serializable {
private String tel;
/**
* 证件类型
1身份证 2护照
3行驶证 99其它
* 证件类型 1身份证 2护照 3行驶证 99其它
*/
@ExcelProperty(value = "证件类型")
private Integer certificateType;
@@ -93,4 +84,10 @@ public class SisPersonLibImgVo implements Serializable {
*/
@ExcelProperty(value = "远程库图像ID")
private Long remoteImgId;
/**
* 人像库id
*/
@ExcelProperty(value = "人像库id")
private Collection<Long> libIds;
}

View File

@@ -1,17 +1,17 @@
package org.dromara.sis.mapper;
import org.apache.ibatis.annotations.Param;
import org.dromara.sis.domain.SisAuthRecord;
import org.dromara.sis.domain.vo.SisAuthRecordVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import java.util.List;
/**
* 授权记录Mapper接口
*
* @author lsm
* @date 2025-06-28
* @since 2025-07-14
*/
public interface SisAuthRecordMapper extends BaseMapperPlus<SisAuthRecord, SisAuthRecordVo> {
SisAuthRecordVo checkAuth(@Param("personId") Integer personId,@Param("accessControlId") Long accessControlId);
List<SisAuthRecordVo> checkAuth(Long personId);
}

View File

@@ -0,0 +1,15 @@
package org.dromara.sis.mapper;
import org.dromara.sis.domain.SisElevatorFloorRef;
import org.dromara.sis.domain.vo.SisElevatorFloorRefVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 电梯⇄楼层关联Mapper接口
*
* @author lsm
* @date 2025-07-15
*/
public interface SisElevatorFloorRefMapper extends BaseMapperPlus<SisElevatorFloorRef, SisElevatorFloorRefVo> {
}

View File

@@ -0,0 +1,15 @@
package org.dromara.sis.mapper;
import org.dromara.sis.domain.SisFloorInfo;
import org.dromara.sis.domain.vo.SisFloorInfoVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 建筑物楼层信息Mapper接口
*
* @author lsm
* @date 2025-07-15
*/
public interface SisFloorInfoMapper extends BaseMapperPlus<SisFloorInfo, SisFloorInfoVo> {
}

View File

@@ -0,0 +1,15 @@
package org.dromara.sis.mapper;
import org.dromara.sis.domain.SisLibImgRef;
import org.dromara.sis.domain.vo.SisLibImgRefVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 人像库-人像图片关联Mapper接口
*
* @author lsm
* @since 2025-07-14
*/
public interface SisLibImgRefMapper extends BaseMapperPlus<SisLibImgRef, SisLibImgRefVo> {
}

View File

@@ -3,34 +3,115 @@ package org.dromara.sis.runner;
import cn.hutool.core.collection.CollUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.sis.domain.bo.SisDeviceManageBo;
import org.dromara.sis.domain.vo.SisDeviceManageVo;
import org.dromara.sis.domain.vo.SisElevatorInfoVo;
import org.dromara.sis.domain.vo.SisFloorInfoVo;
import org.dromara.sis.sdk.hik.HikApiService;
import org.dromara.sis.sdk.hik.calback.HikAlarmCallBack;
import org.dromara.sis.service.ISisDeviceManageService;
import org.dromara.sis.service.ISisElevatorInfoService;
import org.dromara.sis.service.ISisFloorInfoService;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@RequiredArgsConstructor
@Component
@RequiredArgsConstructor
public class HikDeviceApplicationRunner implements ApplicationRunner {
private final HikAlarmCallBack hikAlarmCallBack;
private final ISisFloorInfoService floorInfoService;
private final ISisDeviceManageService deviceManageService;
private final ISisElevatorInfoService elevatorInfoService;
@Override
public void run(ApplicationArguments args) throws Exception {
// 先布放,在登录
HikApiService.getInstance().setAlarmCallBack(0, hikAlarmCallBack);
// 现在查询全部,后面要更具需要查询指定厂商的设备
HikDeviceApplicationRunner runner = SpringUtils.getAopProxy(this);
// 梯控登录
runner.hikElevatorInfoLogin();
// 网络摄像头登录
hikNetCameraLogin();
}
@Async
public void hikElevatorInfoLogin() {
List<SisElevatorInfoVo> sisElevatorInfoVos = elevatorInfoService.queryAll();
if (CollUtil.isNotEmpty(sisElevatorInfoVos)) {
sisElevatorInfoVos.forEach(item -> {
// 执行设备登录操作
HikApiService.getInstance().login(item.getControlIp(), item.getControlPort().shortValue(), item.getControlAccount(), item.getControlPwd());
// todo 更新设备心跳信息
// 根据建筑ID获取楼层信息
SisFloorInfoVo floorInfo = floorInfoService.queryByBuildingId(item.getBuildingId());
// 获取楼层数组
List<Integer> layerArray = generateFloorArray(floorInfo.getMinLayer().intValue(), floorInfo.getMaxLayer().intValue());
// 下发权限
for (int i = 0; i < layerArray.size(); i++) {
HikApiService.getInstance().controlGateway(item.getControlIp(), (i + 1), layerArray.get(i));
}
});
}
// String ip = "192.168.24.188";
// short port = 8000;
// String account = "admin";
// String pwd = "qweasd123";
// HikApiService.getInstance().login(ip, port, account, pwd);
// List<Integer> arrs = Arrays.asList(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2);
// for (int i = 0; i < arrs.size(); i++) {
// HikApiService.getInstance().controlGateway(ip, (i + 1), arrs.get(i));
// }
}
//输入最低层,最高层,返回楼层数组
public List<Integer> generateFloorArray(int minLayer, int maxLayer) {
// 验证输入范围
if (minLayer > maxLayer) {
throw new IllegalArgumentException("最低层不能大于最高层");
}
// 使用List动态收集楼层
List<Integer> layerList = new ArrayList<>();
// 遍历所有楼层跳过0层
for (int layer = minLayer; layer <= maxLayer; layer++) {
if (layer != 0) {
// 初始数组赋值为3不下发权限
layerList.add(3);
}
}
return layerList;
}
@Async
public void hikNetCameraLogin() {
List<SisDeviceManageVo> deviceList = deviceManageService.queryList(new SisDeviceManageBo());
if (CollUtil.isEmpty(deviceList)) {
log.info("没有查询到摄像设备信息,不执行登录");
return;
}
deviceList.forEach(item -> {
int handler = HikApiService.getInstance().login(item.getDeviceIp(), item.getDevicePort().shortValue(), item.getDeviceAccount(), item.getDevicePwd());
if (handler != -1) {
HikApiService.getInstance().setAlarmChan(handler);
}
});
// String ip = "192.168.24.19";
// short port = 8000;
// String account = "admin";
// String pwd = "xzf13579";
// int handler = HikApiService.getInstance().login(ip, port, account, pwd);
}
}

View File

@@ -15,6 +15,16 @@ public class AuthDoorDeviceFindRes {
*/
private Long id;
/**
* 门名称
*/
private String name;
/**
* 设备code
*/
private String deviceNo;
/**
* 门禁Id
*/

View File

@@ -176,7 +176,7 @@ public class DoorDeviceServiceImpl implements DoorDeviceService {
/**
* 分页获取授权门信息
*
* @return TableDataInfo<AuthDoorDeviceFindRes>
* @return List<AuthDoorDeviceFindRes>
*/
public List<AuthDoorDeviceFindRes> getPageAuthDoorDeviceList() {
Map<String, Object> queryDto = new HashMap<>();

View File

@@ -25,6 +25,7 @@ public class HikApiService {
}
private static volatile HikApiService instance;
public static HikApiService getInstance() {
if (instance == null) {
synchronized (HikApiService.class) {
@@ -36,6 +37,9 @@ public class HikApiService {
return instance;
}
public static void init() {
SdkBaseServer.initSdk();
}
/**
@@ -47,13 +51,22 @@ public class HikApiService {
* @param psw 设备密码
* @return 返回会否登录成功
*/
public Boolean login(String ip, short port, String user, String psw) {
public int login(String ip, short port, String user, String psw) {
int i = LoginService.loginDevice(ip, port, user, psw);
boolean result = (i != SdkBaseServer.LOGIN_FAIL_CODE);
if (result) {
CACHE.put(ip, i);
}
return result;
return i;
}
/**
* 注册报警信息回调函数。
*
* @param callBack 报警信回调
*/
public boolean setAlarmCallBack(int iIndex, HCNetSDK.FMSGCallBack_V31 callBack) {
return SdkBaseServer.setAlarmCallBack(iIndex, callBack);
}
/**
@@ -107,4 +120,8 @@ public class HikApiService {
}
return logout;
}
public void setAlarmChan(int handler) {
SdkBaseServer.setAlarmChan(handler);
}
}

View File

@@ -0,0 +1,177 @@
package org.dromara.sis.sdk.hik.calback;
import cn.hutool.core.codec.Base64Encoder;
import cn.hutool.core.collection.CollUtil;
import com.sun.jna.Pointer;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.sis.domain.vo.*;
import org.dromara.sis.sdk.e8.AccessControlService;
import org.dromara.sis.sdk.e8.domain.accessControl.req.RemoteOpenDoorReq;
import org.dromara.sis.sdk.hik.HCNetSDK;
import org.dromara.sis.sdk.hik.HikApiService;
import org.dromara.sis.sdk.huawei.HuaWeiBoxApi;
import org.dromara.sis.service.*;
import org.springframework.stereotype.Component;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@Slf4j
@Component
@RequiredArgsConstructor
public class HikAlarmCallBack implements HCNetSDK.FMSGCallBack_V31 {
private final HuaWeiBoxApi huaWeiBoxApi;
private final ISisFloorInfoService floorInfoService;
private final ISisAuthRecordService authRecordService;
private final ISisElevatorInfoService elevatorInfoService;
private final ISisDeviceBindRefService deviceBindRefService;
private final ISisAccessControlService accessControlService;
private final ISisElevatorFloorRefService elevatorFloorRefService;
private final AccessControlService e8AccessControlService;
private static final int COMM_UPLOAD_FACESNAP_RESULT = 0x1112;
@Override
public boolean invoke(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) {
if (lCommand == COMM_UPLOAD_FACESNAP_RESULT) {// 读取抓拍人脸数据
long s = System.currentTimeMillis();
log.info("hik 抓拍信息上报完成,lCommand={}", lCommand);
HCNetSDK.NET_VCA_FACESNAP_RESULT result = new HCNetSDK.NET_VCA_FACESNAP_RESULT();
result.write();
Pointer pItsPlateInfo = result.getPointer();
pItsPlateInfo.write(0, pAlarmInfo.getByteArray(0, result.size()), 0, result.size());
result.read();
// 读取人脸小图
ByteBuffer buffers = result.pBuffer1.getByteBuffer(0, result.dwFacePicLen);
byte[] smallImg = new byte[result.dwFacePicLen];
buffers.rewind();
buffers.get(smallImg);
// 读取人脸大图
/*ByteBuffer buffers1 = result.pBuffer2.getByteBuffer(0, result.dwBackgroundPicLen);
byte[] bigImg = new byte[result.dwBackgroundPicLen];
buffers1.rewind();
buffers1.get(bigImg);*/
//设备ip
String sAlarmInfo = new String(pAlarmer.sDeviceIP).trim();
// 设备绑定关系
List<SisDeviceBindRefVo> bindRefList = deviceBindRefService.queryByDeviceIp(sAlarmInfo);
if (CollUtil.isEmpty(bindRefList)) {
log.info("当前报警设备未绑定门禁/梯控,不做处理!");
return true;
}
// todo 进行人脸比对
String smallImgBase64Str = Base64Encoder.encode(smallImg);
long s1 = System.currentTimeMillis();
Long person = huaWeiBoxApi.findPerson(smallImgBase64Str);
log.info("人脸比对执行完成,耗时:{}", System.currentTimeMillis() - s1);
if (person == null) {
log.info("未命中人脸数据,暂不处理。");
return true;
}
log.info("人脸比对完成,personId={}", person);
// 授权记录
List<SisAuthRecordVo> authVoList = authRecordService.checkAuth(person);
// 获取门禁id
Collection<Long> acIds = authVoList.stream().filter(vo -> vo.getDeviceType() == 1).map(SisAuthRecordVo::getDeviceId).toList();
if (CollUtil.isNotEmpty(acIds)) {
acIds.forEach(id -> {
Long deviceId = bindRefList.stream().filter(vo -> vo.getBindId().equals(id)).findFirst().map(SisDeviceBindRefVo::getDeviceId).orElse(null);
SisAccessControlVo ac = accessControlService.queryById(deviceId);
if (ac != null) {
log.info("调用门禁服务远程开门");
RemoteOpenDoorReq req = new RemoteOpenDoorReq();
req.setType(0);
RemoteOpenDoorReq.ControlData data = new RemoteOpenDoorReq.ControlData();
data.setDeviceId(Long.parseLong(ac.getOutCode()));
data.setDoorId(Long.parseLong(ac.getOutCode()));
req.setControlList(List.of(data));
Boolean flag = e8AccessControlService.remoteOpenDoor(req);
log.info("远程开门结果,result={}", flag);
}
});
}
// 获取电梯ids
Collection<Long> eleIds = authVoList.stream().filter(vo -> vo.getDeviceType() == 2).map(SisAuthRecordVo::getDeviceId).toList();
if (CollUtil.isNotEmpty(eleIds)) {
eleIds.forEach(id -> {
Long deviceId = bindRefList.stream().filter(vo -> vo.getBindId().equals(id)).findFirst().map(SisDeviceBindRefVo::getDeviceId).orElse(null);
SisElevatorInfoVo ele = elevatorInfoService.queryById(deviceId);
if (ele != null) {
log.info("下发电梯权限");
// 根据建筑ID获取楼层信息
SisFloorInfoVo floorInfo = floorInfoService.queryByBuildingId(ele.getBuildingId());
// 获取电梯⇄楼层关联信息
List<SisElevatorFloorRefVo> floorRefList = elevatorFloorRefService.queryByElevatorId(deviceId);
// 获取楼层数组
List<Integer> layerArray = generateFloorArray(floorInfo.getMinLayer().intValue(), floorInfo.getMaxLayer().intValue());
layerArray.forEach(layer -> {
SisElevatorFloorRefVo floorRef = floorRefList.stream()
.filter(vo -> vo.getLayerNum().intValue() == layer) // 直接使用 layer
.findFirst()
.orElse(null);
if (floorRef == null) {
HikApiService.getInstance().controlGateway(ele.getControlIp(), layer, 3);
} else {
HikApiService.getInstance().controlGateway(ele.getControlIp(), layer, 2);
}
});
}
});
}
// List<Integer> arrs = Arrays.asList(2, 2, 2, 3, 3, 3 ,3, 3, 3, 3, 3, 3, 3, 3, 3, 3);
// List<Integer> arrs = Arrays.asList(3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2);
// for (int i = 0; i < arrs.size(); i++) {
// HikApiService.getInstance().controlGateway("192.168.24.188", (i + 1), arrs.get(i));
// }
// log.info("权限下发执行完成,耗时:{}", System.currentTimeMillis() - s);
// try {
// Thread.sleep(10000L);
// List<Integer> ass = Arrays.asList(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3);
// for (int i = 0; i < arrs.size(); i++) {
// HikApiService.getInstance().controlGateway("192.168.24.188", (i + 1), arrs.get(i));
// }
// } catch (InterruptedException e) {
// throw new RuntimeException(e);
// }
} else {
log.info("未知报警类型,lCommand={}", lCommand);
}
return true;
}
//输入最低层,最高层,返回楼层数组
public List<Integer> generateFloorArray(int minLayer, int maxLayer) {
// 验证输入范围
if (minLayer > maxLayer) {
throw new IllegalArgumentException("最低层不能大于最高层");
}
// 使用List动态收集楼层
List<Integer> layerList = new ArrayList<>();
// 遍历所有楼层跳过0层
for (int layer = minLayer; layer <= maxLayer; layer++) {
if (layer != 0) {
layerList.add(layer);
}
}
return layerList;
}
}

View File

@@ -182,6 +182,7 @@ public class DoorService extends SdkBaseServer {
public static boolean controlGateway(int lUserID, int lGatewayIndex, int dwStaic) {
boolean b = getHcNetSDK().NET_DVR_ControlGateway(lUserID, lGatewayIndex, dwStaic);
log.info("楼层数据下发结果,楼层={}result={}", lGatewayIndex, b);
if (!b) {
int i = getHcNetSDK().NET_DVR_GetLastError();
log.error("梯控控制失败, errCode={}", i);

View File

@@ -1,6 +1,7 @@
package org.dromara.sis.sdk.hik.service;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import lombok.extern.slf4j.Slf4j;
import org.dromara.sis.sdk.hik.HCNetSDK;
import org.springframework.util.Assert;
@@ -18,7 +19,6 @@ public class SdkBaseServer {
*/
public static final int LOGIN_FAIL_CODE = -1;
public static HCNetSDK getHcNetSDK() {
if (hcNetSDK == null) {
throw new RuntimeException("HIK sdk 初始化失败!");
@@ -83,6 +83,41 @@ public class SdkBaseServer {
return state;
}
/**
* 开启hik 设备报警
*
* @param iIndex 回调函数索引,取值范围:[0,15]
* @param callBack 回调函数
* @return
*/
public static boolean setAlarmCallBack(int iIndex, HCNetSDK.FMSGCallBack_V31 callBack) {
boolean b = hcNetSDK.NET_DVR_SetDVRMessageCallBack_V50(iIndex, callBack, null);
if (b) {
log.info("hik 报警回调函数设置完成iIndex={}", iIndex);
}
return b;
}
public static boolean setAlarmChan(int lUserID){
//报警布防参数设置
HCNetSDK.NET_DVR_SETUPALARM_PARAM_V50 m_strAlarmInfoV50 = new HCNetSDK.NET_DVR_SETUPALARM_PARAM_V50();
m_strAlarmInfoV50.dwSize = m_strAlarmInfoV50.size();
m_strAlarmInfoV50.byLevel = 0; //布防等级
m_strAlarmInfoV50.byAlarmInfoType = 1; // 智能交通报警信息上传类型0- 老报警信息NET_DVR_PLATE_RESULT1- 新报警信息(NET_ITS_PLATE_RESULT)
m_strAlarmInfoV50.byRetAlarmTypeV40 = 1; //0- 移动侦测、视频丢失、遮挡、IO信号量等报警信息以普通方式上传报警类型COMM_ALARM_V30报警信息结构体NET_DVR_ALARMINFO_V30
// 1- 报警信息以数据可变长方式上传报警类型COMM_ALARM_V40报警信息结构体NET_DVR_ALARMINFO_V40设备若不支持则仍以普通方式上传
m_strAlarmInfoV50.byDeployType = 0; //布防类型0-客户端布防1-实时布防
m_strAlarmInfoV50.write();
int lAlarmHandle = hcNetSDK.NET_DVR_SetupAlarmChan_V50(lUserID, m_strAlarmInfoV50, Pointer.NULL, 0);
if (lAlarmHandle == -1) {
System.err.println("布防失败,错误码为" + hcNetSDK.NET_DVR_GetLastError());
return false;
} else {
System.out.println("布防成功");
return true;
}
}
/**
* 登出操作

View File

@@ -1,7 +1,6 @@
package org.dromara.sis.sdk.huawei;
import org.dromara.sis.sdk.huawei.domain.AddHWPersonReq;
import org.dromara.sis.sdk.huawei.domain.FinaHWPersonReq;
import java.util.Collection;
import java.util.List;
@@ -32,8 +31,8 @@ public interface HuaWeiBoxApi {
/**
* 根据抓拍图片比对返回人员ID
*
* @param req 入参
* @param base64Img 入参
* @return Long
*/
Long findPerson(FinaHWPersonReq req);
Long findPerson(String base64Img);
}

View File

@@ -8,7 +8,6 @@ import lombok.NoArgsConstructor;
* @apiNote FinaHWPersonReq
* @since 2025/7/10
*/
@NoArgsConstructor
@Data
public class FinaHWPersonReq {
/**
@@ -23,6 +22,11 @@ public class FinaHWPersonReq {
* page
*/
private PageDTO page;
public FinaHWPersonReq() {
this.page = new PageDTO(); // 显式初始化 page
}
/**
* picture
*/

View File

@@ -82,25 +82,35 @@ public class HuaWeiBoxApiService implements HuaWeiBoxApi {
/**
* 根据抓拍图片比对返回人员ID
*
* @param req 入参
* @param base64Img 入参
* @return Long
*/
@Override
public Long findPerson(FinaHWPersonReq req){
public Long findPerson(String base64Img) {
String url = "/sdk_service/rest/facerepositories/peoples";
FinaHWPersonReq req = new FinaHWPersonReq();
FinaHWPersonReq.PictureDTO picture = new FinaHWPersonReq.PictureDTO();
picture.setBase64(base64Img);
req.setPicture(picture);
String jsonReq = JSONUtil.toJsonStr(req);
String jsonStrRes = huaWeiHttp.doPost(url, jsonReq);
JSONObject jsonRes = JSONUtil.parseObj(jsonStrRes);
if (jsonRes.getInt("resultCode") != 0) {
log.error("华为盒子人脸比对msg{}", jsonRes.getStr("resultMsg"));
log.error("调用华为盒子人脸比对接口失败code:{}msg{}", jsonRes.getInt("resultCode"), jsonRes.getStr("resultMsg"));
return null;
}
JSONArray jsonArr = jsonRes.getJSONArray("algorithmCode");
JSONArray jsonArr = jsonRes.getJSONArray("algorithmResults");
JSONObject obj = jsonArr.getJSONObject(0);
if (Integer.parseInt(obj.getStr("number")) == 0) {
log.error("无人脸比对数据");
return null;
}
JSONArray peopleList = obj.getJSONArray("peopleList");
JSONObject people = peopleList.getJSONObject(0);

View File

@@ -11,6 +11,10 @@ import org.dromara.common.redis.utils.RedisUtils;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
/**
* @author lsm
@@ -21,7 +25,7 @@ import java.util.Map;
@Component
public class HuaWeiHttp {
private static final String BASE_URL = "https://192.168.110.195:18531";
private static final String BASE_URL = "https://47.109.37.87:18000";
private static final String USERNAME = "huawei";
private static final String PASSWORD = "qweasd123";
@@ -37,13 +41,14 @@ public class HuaWeiHttp {
// 发送请求获取响应
// 使用 try-with-resources 确保资源释放
try (HttpResponse response = HttpRequest.post(url)
.header("Content-Type", "application/json")
.header("Cache-Control", "no-cache")
.body(jsonStr)
.execute()) {
.header("Content-Type", "application/json")
.header("Cache-Control", "no-cache")
.body(jsonStr)
.execute()) {
if (response.getStatus() == 200 && response.getCookie("JSESSIONID") != null) {
RedisUtils.setCacheObject("JSESSIONID", response.getCookie("JSESSIONID").toString());
RedisUtils.expire("JSESSIONID", 1800);
this.keepAlive();
return true;
} else {
log.error("华为盒子登录失败msg{}", response.body());
@@ -52,6 +57,66 @@ public class HuaWeiHttp {
return false;
}
// 保活
public void keepAlive() {
// 创建单线程调度器
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
String url = BASE_URL + "/common/keepAlive";
// 保存任务引用,用于后续取消
final ScheduledFuture<?>[] heartbeatFuture = new ScheduledFuture<?>[1];
// 心跳任务
Runnable heartbeatTask = () -> {
log.info("开始心跳执行华为盒子Session保活");
// 发送请求获取响应
// 使用 try-with-resources 确保资源释放
try (HttpResponse response = HttpRequest.post(url)
.header("Content-Type", "application/json")
.header("Cache-Control", "no-cache")
.header("Cookie", RedisUtils.getCacheObject("JSESSIONID"))
.execute()) {
if (response.getStatus() == 200 && JSONUtil.parseObj(response.body()).getInt("resultCode") == 0) {
RedisUtils.expire("JSESSIONID", 1800);
log.info("保活成功");
}else {
log.info("保活失败");
shutdownHeartbeat(scheduler, heartbeatFuture[0]);
}
} catch (Exception e) {
// 异常:立即关闭心跳
log.error("保活请求异常: {}", e.getMessage());
shutdownHeartbeat(scheduler, heartbeatFuture[0]);
}
};
// 初始延迟0秒之后每20分钟执行一次
heartbeatFuture[0] = scheduler.scheduleAtFixedRate(heartbeatTask, 20, 20, TimeUnit.MINUTES);
log.info("心跳任务已启动首次执行将在20分钟后");
// 添加关闭钩子确保程序退出时关闭调度器
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
if (!scheduler.isShutdown()) {
scheduler.shutdown();
log.info("程序退出,心跳调度器已关闭");
}
}));
}
private static void shutdownHeartbeat(ScheduledExecutorService scheduler, ScheduledFuture<?> future) {
// 取消心跳任务
if (future != null && !future.isCancelled()) {
future.cancel(false);
log.error("保活失败,心跳任务已取消");
}
// 关闭调度器
if (!scheduler.isShutdown()) {
scheduler.shutdown();
log.info("心跳调度器已关闭");
}
}
/**
* 发起Post请求
*
@@ -70,11 +135,11 @@ public class HuaWeiHttp {
String api = BASE_URL + url;
try (HttpResponse response = HttpRequest.post(api)
.header("Content-Type", "application/json")
.header("Cache-Control", "no-cache")
.header("Cookie", RedisUtils.getCacheObject("JSESSIONID"))
.body(jsonStr)
.execute()) {
.header("Content-Type", "application/json")
.header("Cache-Control", "no-cache")
.header("Cookie", RedisUtils.getCacheObject("JSESSIONID"))
.body(jsonStr)
.execute()) {
if (response.isOk()) {
return response.body();
} else {
@@ -109,10 +174,10 @@ public class HuaWeiHttp {
String fullUrl = HttpUtil.urlWithForm(api, map, null, false);
try (HttpResponse response = HttpRequest.delete(fullUrl)
.header("Content-Type", "application/json")
.header("Cache-Control", "no-cache")
.header("Cookie", RedisUtils.getCacheObject("JSESSIONID"))
.execute()) {
.header("Content-Type", "application/json")
.header("Cache-Control", "no-cache")
.header("Cookie", RedisUtils.getCacheObject("JSESSIONID"))
.execute()) {
return response.body();
}
}

View File

@@ -3,11 +3,8 @@ package org.dromara.sis.sdk.unview.service;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.sis.domain.SisDeviceBindRef;
import org.dromara.sis.domain.enums.ControlTypeEnum;
import org.dromara.sis.domain.vo.SisAuthRecordVo;
import org.dromara.sis.sdk.e8.AccessControlService;
import org.dromara.sis.sdk.e8.domain.accessControl.req.RemoteOpenDoorReq;
import org.dromara.sis.sdk.hik.HikApiService;
import org.dromara.sis.sdk.unview.model.UvModel;
import org.dromara.sis.sdk.unview.model.enums.AlarmTypeEnum;
import org.dromara.sis.service.ISisAccessControlService;
@@ -16,8 +13,8 @@ import org.dromara.sis.service.ISisDeviceBindRefService;
import org.dromara.sis.service.ISisDeviceManageService;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
/**
* 宇视人体设备告警数据处理
@@ -111,6 +108,7 @@ public class VideoAlarmService {
*/
private void handleFacialCapture(UvModel.AlarmReportInfo alarmReportData) {
}
/**
@@ -130,54 +128,57 @@ public class VideoAlarmService {
log.info("上报设备信息不存在,不处理词条数据。");
return;
}
log.info("开始电梯权限下发。。。。。。。。。。。。。。。。。。。。。。");
compareResults.forEach(result -> {
// 查询设备绑定关联关系表
SisDeviceBindRef ref = deviceBindRefService.queryByDeviceIp(channelInfo.getIpc_addr());
if (ref == null) {
return;
}
// 门禁
if (Objects.equals(ref.getControlType(), ControlTypeEnum.ACCESS_CONTROL.getCode())) {
// SisAccessControlVo controlVo = sisAccessControlService.queryById(ref.getBindId());
// if (controlVo == null) {
// log.info("设备[{}]未和门禁绑定,不处理此条数据。", channelInfo.getIpc_addr());
// return;
// }
// 人像库id
// Integer libId = result.getLib_id();
// 宇视人员id
Integer personId = result.getPerson_id();
// 门禁id
Long accessControlId = ref.getBindId();
// 校验人脸是偶有同行此门禁的权限
SisAuthRecordVo recordVo = authRecordService.checkAuth(personId, accessControlId);
// 如果有通行权限,则打开门禁
if (recordVo == null) {
log.info("此人像[{}]没有门禁[{}]的通行权限。", personId, accessControlId);
}
// 打开门禁
RemoteOpenDoorReq remoteOpenDoorReq = new RemoteOpenDoorReq();
remoteOpenDoorReq.setType(0);
remoteOpenDoorReq.setReason("宇视人像识别,人像id=" + recordVo.getImgId());
remoteOpenDoorReq.setOperatorId(0L);
RemoteOpenDoorReq.ControlData data = new RemoteOpenDoorReq.ControlData();
data.setDoorId(recordVo.getDoorId());
data.setDeviceId(recordVo.getDeviceId());
remoteOpenDoorReq.setControlList(List.of(data));
log.info("远程开门参数params={}", JSONObject.toJSONString(remoteOpenDoorReq));
Boolean b = accessControlService.remoteOpenDoor(remoteOpenDoorReq);
log.info("远程开门完成, result={}", b);
}
// 远程呼梯
if (Objects.equals(ref.getControlType(), ControlTypeEnum.REMOTE_CALL_ELEVATOR.getCode())) {
// TODO 待实现
// 下发梯控权限数据
// List<Integer> arrs = Arrays.asList(2, 2, 2, 3, 3, 3 ,3, 3, 3, 3, 3, 3, 3, 3, 3, 3);
List<Integer> arrs = Arrays.asList(3, 3, 3, 2, 2, 2 ,2, 2, 2, 2, 2, 2, 2, 2, 2, 2);
for (int i = 0; i < arrs.size(); i++) {
HikApiService.getInstance().controlGateway("192.168.24.188", (i + 1), arrs.get(i));
}
// 梯控
if (Objects.equals(ref.getControlType(), ControlTypeEnum.ELEVATOR_CONTROL.getCode())) {
// TODO 待实现
}
});
// compareResults.forEach(result -> {
// // 查询设备绑定关联关系表
// SisDeviceBindRef ref = deviceBindRefService.queryByDeviceIp(channelInfo.getIpc_addr());
// if (ref == null) {
// return;
// }
// // 门禁
// if (Objects.equals(ref.getControlType(), ControlTypeEnum.ACCESS_CONTROL.getCode())) {
// // 宇视人员id
// Integer personId = result.getPerson_id();
// // 门禁id
// Long accessControlId = ref.getBindId();
// // 校验人脸是偶有同行此门禁的权限
// SisAuthRecordVo recordVo = authRecordService.checkAuth(personId, accessControlId);
// // 如果有通行权限,则打开门禁
// if (recordVo == null) {
// log.info("此人像[{}]没有门禁[{}]的通行权限。", personId, accessControlId);
// }
// // 打开门禁
// RemoteOpenDoorReq remoteOpenDoorReq = new RemoteOpenDoorReq();
// remoteOpenDoorReq.setType(0);
// remoteOpenDoorReq.setReason("宇视人像识别,人像id=" + recordVo.getImgId());
// remoteOpenDoorReq.setOperatorId(0L);
// RemoteOpenDoorReq.ControlData data = new RemoteOpenDoorReq.ControlData();
// data.setDoorId(recordVo.getDoorId());
// data.setDeviceId(recordVo.getDeviceId());
// remoteOpenDoorReq.setControlList(List.of(data));
// log.info("远程开门参数params={}", JSONObject.toJSONString(remoteOpenDoorReq));
// Boolean b = accessControlService.remoteOpenDoor(remoteOpenDoorReq);
// log.info("远程开门完成, result={}", b);
// }
// // 远程呼梯
// if (Objects.equals(ref.getControlType(), ControlTypeEnum.REMOTE_CALL_ELEVATOR.getCode())) {
// // TODO 待实现
// }
//
// // 梯控
// if (Objects.equals(ref.getControlType(), ControlTypeEnum.ELEVATOR_CONTROL.getCode())) {
// // TODO 待实现
// }
// });
}
/**

View File

@@ -82,4 +82,11 @@ public interface ISisAccessControlService {
*/
List<TreeNode<Long>> queryAcTree();
/**
* 同步门禁设备
*
* @return Boolean
*/
Boolean syncE8();
}

View File

@@ -1,12 +1,11 @@
package org.dromara.sis.service;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.core.domain.TreeNode;
import org.dromara.sis.domain.SisAuthRecord;
import org.dromara.sis.domain.bo.AuthLibBo;
import org.dromara.sis.domain.bo.SingleAuthRecordBo;
import org.dromara.sis.domain.bo.SisAuthRecordBo;
import org.dromara.sis.domain.vo.SisAuthRecordVo;
import org.dromara.sis.domain.bo.SisAuthRecordBo;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
@@ -15,7 +14,7 @@ import java.util.List;
* 授权记录Service接口
*
* @author lsm
* @date 2025-06-28
* @since 2025-07-14
*/
public interface ISisAuthRecordService {
@@ -70,30 +69,31 @@ public interface ISisAuthRecordService {
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* 通过宇视图片id和门禁id校验此图像是否有通行权限
* 查询库id授权的设备
*
* @param personId 人像id
* @param accessControlId 门禁id
* @return 返回授权记录
*/
SisAuthRecordVo checkAuth(Integer personId, Long accessControlId);
/**
* 单个人像授权
*
* @param bo 授权信息
* @return 是否授权成功
*/
Boolean singleAuth(SingleAuthRecordBo bo);
Boolean deleteByLibId(Long libId);
Boolean authLib(AuthLibBo bo);
/**
* 插叙库id授权的设备
* @param libId 人像库id
* @return
* @return List<SisAuthRecord>
*/
List<SisAuthRecord> queryAuthDevice(String libId);
/**
* 根据人像库id删除授权记录
*
* @param libId 人像库id
*/
Boolean deleteByLibId(Long libId);
/**
* 查询所有可授权设备树
*
* @return List<TreeNode<Long>>
*/
List<TreeNode<Long>> authDeviceTree();
/**
* 根据人脸比对ID返回授权记录
*
* @param personId 人脸比对ID
*/
List<SisAuthRecordVo> checkAuth(Long personId);
}

View File

@@ -81,7 +81,7 @@ public interface ISisDeviceBindRefService {
* @param ipcAddr 设备ip
* @return 返回关联关系表
*/
SisDeviceBindRef queryByDeviceIp(String ipcAddr);
List<SisDeviceBindRefVo> queryByDeviceIp(String ipcAddr);
/**
* 批量写入设备绑定关系

View File

@@ -0,0 +1,75 @@
package org.dromara.sis.service;
import org.dromara.sis.domain.vo.SisElevatorFloorRefVo;
import org.dromara.sis.domain.bo.SisElevatorFloorRefBo;
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 lsm
* @since 2025-07-15
*/
public interface ISisElevatorFloorRefService {
/**
* 查询电梯⇄楼层关联
*
* @param id 主键
* @return 电梯⇄楼层关联
*/
SisElevatorFloorRefVo queryById(Long id);
/**
* 分页查询电梯⇄楼层关联列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 电梯⇄楼层关联分页列表
*/
TableDataInfo<SisElevatorFloorRefVo> queryPageList(SisElevatorFloorRefBo bo, PageQuery pageQuery);
/**
* 查询符合条件的电梯⇄楼层关联列表
*
* @param bo 查询条件
* @return 电梯⇄楼层关联列表
*/
List<SisElevatorFloorRefVo> queryList(SisElevatorFloorRefBo bo);
/**
* 新增电梯⇄楼层关联
*
* @param bo 电梯⇄楼层关联
* @return 是否新增成功
*/
Boolean insertByBo(SisElevatorFloorRefBo bo);
/**
* 修改电梯⇄楼层关联
*
* @param bo 电梯⇄楼层关联
* @return 是否修改成功
*/
Boolean updateByBo(SisElevatorFloorRefBo bo);
/**
* 校验并批量删除电梯⇄楼层关联信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* 根据电梯id获取电梯⇄楼层关联信息
*
* @param elevatorId 电梯id
*/
List<SisElevatorFloorRefVo> queryByElevatorId(Long elevatorId);
}

View File

@@ -71,4 +71,12 @@ public interface ISisElevatorInfoService {
* @return 返回电梯列表
*/
List<SisElevatorInfoVo> queryAll();
/**
* 根据查询列表
*
* @param ids 电梯id
* @return 列表
*/
List<SisElevatorInfoVo> queryListByIds(Collection<Long> ids);
}

View File

@@ -0,0 +1,76 @@
package org.dromara.sis.service;
import org.dromara.sis.domain.vo.SisFloorInfoVo;
import org.dromara.sis.domain.bo.SisFloorInfoBo;
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 lsm
* @since 2025-07-15
*/
public interface ISisFloorInfoService {
/**
* 查询建筑物楼层信息
*
* @param floorId 主键
* @return 建筑物楼层信息
*/
SisFloorInfoVo queryById(Long floorId);
/**
* 分页查询建筑物楼层信息列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 建筑物楼层信息分页列表
*/
TableDataInfo<SisFloorInfoVo> queryPageList(SisFloorInfoBo bo, PageQuery pageQuery);
/**
* 查询符合条件的建筑物楼层信息列表
*
* @param bo 查询条件
* @return 建筑物楼层信息列表
*/
List<SisFloorInfoVo> queryList(SisFloorInfoBo bo);
/**
* 新增建筑物楼层信息
*
* @param bo 建筑物楼层信息
* @return 是否新增成功
*/
Boolean insertByBo(SisFloorInfoBo bo);
/**
* 修改建筑物楼层信息
*
* @param bo 建筑物楼层信息
* @return 是否修改成功
*/
Boolean updateByBo(SisFloorInfoBo bo);
/**
* 校验并批量删除建筑物楼层信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* 根据建筑ID返回楼层信息
*
* @param buildingId 建筑ID
* @return 楼层信息
*/
SisFloorInfoVo queryByBuildingId(Long buildingId);
}

View File

@@ -0,0 +1,77 @@
package org.dromara.sis.service;
import org.dromara.sis.domain.SisLibImgRef;
import org.dromara.sis.domain.vo.SisLibImgRefVo;
import org.dromara.sis.domain.bo.SisLibImgRefBo;
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 lsm
* @since 2025-07-14
*/
public interface ISisLibImgRefService {
/**
* 查询人像库-人像图片关联
*
* @param libId 主键
* @return 人像库-人像图片关联
*/
SisLibImgRefVo queryById(Long libId);
/**
* 分页查询人像库-人像图片关联列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 人像库-人像图片关联分页列表
*/
TableDataInfo<SisLibImgRefVo> queryPageList(SisLibImgRefBo bo, PageQuery pageQuery);
/**
* 查询符合条件的人像库-人像图片关联列表
*
* @param bo 查询条件
* @return 人像库-人像图片关联列表
*/
List<SisLibImgRefVo> queryList(SisLibImgRefBo bo);
/**
* 新增人像库-人像图片关联
*
* @param bo 人像库-人像图片关联
* @return 是否新增成功
*/
Boolean insertByBo(SisLibImgRefBo bo);
/**
* 修改人像库-人像图片关联
*
* @param bo 人像库-人像图片关联
* @return 是否修改成功
*/
Boolean updateByBo(SisLibImgRefBo bo);
/**
* 校验并批量删除人像库-人像图片关联信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* 批量添加人像库-人像图片关联
*
* @param refs 待添加的关联信息
* @return 是否添加成功
*/
Boolean addBatch(List<SisLibImgRef> refs);
}

View File

@@ -15,7 +15,6 @@ 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.property.api.RemoteFloorService;
import org.dromara.property.api.domain.vo.RemoteFloorVo;
import org.dromara.sis.domain.SisAccessControl;
import org.dromara.sis.domain.SisDeviceBindRef;
import org.dromara.sis.domain.bo.SisAccessControlBo;
@@ -24,14 +23,14 @@ import org.dromara.sis.domain.vo.SisAccessControlVo;
import org.dromara.sis.domain.vo.SisDeviceManageVo;
import org.dromara.sis.mapper.SisAccessControlMapper;
import org.dromara.sis.sdk.e8.DoorDeviceService;
import org.dromara.sis.sdk.e8.domain.door.req.DoorDeviceAddReq;
import org.dromara.sis.sdk.e8.domain.door.res.DoorDeviceAddRes;
import org.dromara.sis.sdk.e8.domain.door.res.AuthDoorDeviceFindRes;
import org.dromara.sis.service.ISisAccessControlService;
import org.dromara.sis.service.ISisDeviceBindRefService;
import org.dromara.sis.service.ISisDeviceManageService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -96,12 +95,10 @@ public class SisAccessControlServiceImpl implements ISisAccessControlService {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<SisAccessControl> lqw = Wrappers.lambdaQuery();
lqw.orderByAsc(SisAccessControl::getId);
// lqw.eq(StringUtils.isNotBlank(bo.getAccessCode()), SisAccessControl::getAccessCode, bo.getAccessCode());
lqw.like(StringUtils.isNotBlank(bo.getAccessName()), SisAccessControl::getAccessName, bo.getAccessName());
lqw.eq(StringUtils.isNotBlank(bo.getAccessIp()), SisAccessControl::getAccessIp, bo.getAccessIp());
lqw.eq(bo.getAccessPort() != null, SisAccessControl::getAccessPort, bo.getAccessPort());
lqw.eq(bo.getAccessType() != null, SisAccessControl::getAccessType, bo.getAccessType());
// lqw.eq(StringUtils.isNotBlank(bo.getFactoryCode()), SisAccessControl::getFactoryCode, bo.getFactoryCode());
lqw.eq(bo.getControlType() != null, SisAccessControl::getControlType, bo.getControlType());
lqw.eq(StringUtils.isNotBlank(bo.getControlCode()), SisAccessControl::getControlCode, bo.getControlCode());
lqw.eq(StringUtils.isNotBlank(bo.getOutCode()), SisAccessControl::getOutCode, bo.getOutCode());
@@ -123,63 +120,7 @@ public class SisAccessControlServiceImpl implements ISisAccessControlService {
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean insertByBo(SisAccessControlBo bo) {
// 校验楼层是否存在
RemoteFloorVo remoteFloorVo = remoteFloorService.queryByFloorId(bo.getFloorId());
Assert.notNull(remoteFloorVo, "当前楼层信息不存在。");
// 检验设备是否存在
SisDeviceManageVo sisDeviceManageVo = sisDeviceManageService.queryById(bo.getBindDeviceId());
Assert.notNull(sisDeviceManageVo, "绑定设备不存在。");
SisAccessControl add = MapstructUtils.convert(bo, SisAccessControl.class);
add.setCommunityId(remoteFloorVo.getCommunityId());
add.setBuildingId(remoteFloorVo.getBuildingId());
add.setUnitId(remoteFloorVo.getUnitId());
add.setFloorId(remoteFloorVo.getId());
Assert.notNull(add, "数据处理失败");
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
// 写入关联关系表中
SisDeviceBindRef sisDeviceBindRef = new SisDeviceBindRef();
sisDeviceBindRef.setDeviceId(sisDeviceManageVo.getId());
sisDeviceBindRef.setDeviceIp(sisDeviceManageVo.getDeviceIp());
sisDeviceBindRef.setBindId(add.getId());
sisDeviceBindRef.setControlType(ControlTypeEnum.ACCESS_CONTROL.getCode());
Boolean insert = sisDeviceBindRefService.insert(sisDeviceBindRef);
Assert.isTrue(insert, "写入设备关联表失败!");
// 添加E8门禁设备
if (add.getControlType() == 2L) {
log.info("开始同步写入E8门禁");
DoorDeviceAddReq e8DoorReq = new DoorDeviceAddReq();
// 设备类型
e8DoorReq.setType(add.getAccessType());
// 设备名称
e8DoorReq.setName(add.getAccessName());
// 通讯类型
e8DoorReq.setCommType(0);
// cpuid
e8DoorReq.setCpuID("");
// ip
e8DoorReq.setIp(add.getAccessIp());
// 端口
e8DoorReq.setPort(add.getAccessPort());
// 网关ip
e8DoorReq.setGatewayIP("");
// 子网掩码
e8DoorReq.setNetMask("255.255.255.0");
DoorDeviceAddRes e8DoorRes = doorDeviceService.addDoorDevice(e8DoorReq);
Assert.notNull(e8DoorRes, "写入E8平台失败");
log.info("E8平台写入成功将返回值{},回写到{}门禁中!", e8DoorRes.getId(), add.getAccessName());
SisAccessControlBo wbBo = new SisAccessControlBo();
wbBo.setId(add.getId());
wbBo.setOutCode(e8DoorRes.getId().toString());
Boolean update = this.updateByBo(wbBo);
Assert.isTrue(update, "外部编码回写失败");
log.info("E8平台写入完成!");
}
}
return flag;
return true;
}
/**
@@ -225,10 +166,7 @@ public class SisAccessControlServiceImpl implements ISisAccessControlService {
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
return true;
}
/**
@@ -260,4 +198,43 @@ public class SisAccessControlServiceImpl implements ISisAccessControlService {
}
return TreeUtils.build(treeNodes, 0L);
}
/**
* 同步门禁设备
*
* @return Boolean
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean syncE8() {
List<AuthDoorDeviceFindRes> authDoorDeviceFindRes = doorDeviceService.getPageAuthDoorDeviceList();
LambdaQueryWrapper<SisAccessControl> lqw = Wrappers.lambdaQuery();
lqw.eq(true, SisAccessControl::getControlType, 2);
List<SisAccessControlVo> sisAccessControlVos = baseMapper.selectVoList(lqw);
// 过滤掉authDoorDeviceFindRes中与sisAccessControlVos具有相同 deviceId 和 outCode 的项
List<AuthDoorDeviceFindRes> filter = authDoorDeviceFindRes.stream()
.filter(res -> sisAccessControlVos.stream()
.noneMatch(vo -> vo.getOutCode().equals(res.getDeviceId().toString())))
.toList();
Collection<SisAccessControl> sisACBos = new ArrayList<>();
for (AuthDoorDeviceFindRes res : filter){
SisAccessControl ac = new SisAccessControl();
ac.setFactoryCode(res.getDeviceNo());
ac.setAccessCode(res.getDeviceId().toString());
ac.setOutCode(res.getDeviceId().toString());
ac.setOutDoorCode(res.getId().toString());
ac.setAccessType(1);
ac.setControlType(2);
ac.setAccessName(res.getName());
ac.setBuildingId(0L);
ac.setCommunityId(0L);
ac.setAccessIp("127.0.0.1");
ac.setAccessPort(8080);
sisACBos.add(ac);
}
return baseMapper.insertBatch(sisACBos);
}
}

View File

@@ -1,66 +1,49 @@
package org.dromara.sis.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.lang.Assert;
import org.dromara.common.core.domain.TreeNode;
import org.dromara.common.core.utils.MapstructUtils;
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 com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.resource.api.RemoteFileService;
import org.dromara.sis.domain.SisAuthRecord;
import org.dromara.sis.domain.SisDeviceManage;
import org.dromara.sis.domain.bo.AuthLibBo;
import org.dromara.sis.domain.bo.SingleAuthRecordBo;
import org.dromara.sis.domain.bo.SisAccessControlBo;
import org.dromara.sis.domain.bo.SisElevatorInfoBo;
import org.dromara.sis.domain.vo.SisAccessControlVo;
import org.dromara.sis.domain.vo.SisElevatorInfoVo;
import org.dromara.sis.service.ISisAccessControlService;
import org.dromara.sis.service.ISisElevatorInfoService;
import org.springframework.stereotype.Service;
import org.dromara.sis.domain.bo.SisAuthRecordBo;
import org.dromara.sis.domain.vo.SisAuthRecordVo;
import org.dromara.sis.domain.SisAuthRecord;
import org.dromara.sis.mapper.SisAuthRecordMapper;
import org.dromara.sis.sdk.e8.AccessControlService;
import org.dromara.sis.sdk.e8.DoorDeviceService;
import org.dromara.sis.sdk.e8.VoucherControlService;
import org.dromara.sis.sdk.unview.UnViewAiBoxApi;
import org.dromara.sis.service.*;
import org.springframework.stereotype.Service;
import org.dromara.sis.service.ISisAuthRecordService;
import org.springframework.transaction.annotation.Transactional;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* 授权记录Service业务层处理
*
* @author lsm
* @since 2025-06-28
* @since 2025-07-14
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class SisAuthRecordServiceImpl implements ISisAuthRecordService {
private final UnViewAiBoxApi unViewAiBoxApi;
private final SisAuthRecordMapper baseMapper;
private final VoucherControlService e8VouchService;
private final DoorDeviceService e8DoorDeviceService;
private final ISisPersonLibService sisPersonLibService;
private final ISisEEightRefService sisEEightRefService;
private final AccessControlService e8AccessControlService;
private final ISisPersonLibImgService sisPersonLibImgService;
private final ISisLibDeviceRefService sisLibDeviceRefService;
private final ISisAccessControlService sisAccessControlService;
private final ISisLibDeviceImgRefService sisLibDeviceImgRefService;
private final ISisDeviceManageService deviceManageService;
@DubboReference
private final RemoteFileService remoteFileService;
private final ISisAccessControlService accessControlService;
private final ISisElevatorInfoService elevatorInfoService;
/**
* 查询授权记录
@@ -82,7 +65,7 @@ public class SisAuthRecordServiceImpl implements ISisAuthRecordService {
*/
@Override
public TableDataInfo<SisAuthRecordVo> queryPageList(SisAuthRecordBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<SisAuthRecord> lqw = Wrappers.lambdaQuery();
LambdaQueryWrapper<SisAuthRecord> lqw = buildQueryWrapper(bo);
Page<SisAuthRecordVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
@@ -116,184 +99,49 @@ public class SisAuthRecordServiceImpl implements ISisAuthRecordService {
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean insertByBo(SisAuthRecordBo bo) {
// List<SisLibDeviceRefVo> refVos = sisLibDeviceRefService.queryByLibIds(Collections.singleton(bo.getLibId()));
// Assert.notEmpty(refVos, "图像库与设备关联关系不存在");
// List<Long> eqpIds = refVos.stream().map(SisLibDeviceRefVo::getEqpId).toList();
//
// SisPersonLibVo libVo = sisPersonLibService.queryById(bo.getLibId());
// Assert.notNull(libVo, "图像库不存在id=" + (bo.getLibId()));
//
// List<SisPersonLibImgVo> imgList = sisPersonLibImgService.queryListByIds(bo.getImgIds());
// Assert.notEmpty(imgList, "图片不存在");
//
// List<SisAccessControlVo> acList = sisAccessControlService.queryListByIds(bo.getAcIds());
// Assert.notEmpty(acList, "门禁设备不存在!");
//
//
// try {
// log.info("开始对宇视盒子下发照片,图片:{}、设备:{}", bo.getImgIds(), eqpIds);
// for (SisPersonLibImgVo imgVo : imgList) {
// for (Long eqpId : eqpIds) {
// long eqp_lib_id;
// Integer eqp_lib_img_id;
//
// byte[] imageByte = remoteFileService.downloadToByteArray(imgVo.getImgOssId());
// Assert.notNull(imageByte, "图片下载失败");
//
// SisAccessControlDeviceVo vo = sisAccessControlDeviceService.queryById(eqpId);
// Assert.notNull(vo, "门禁控制设备不存在id=" + eqpId);
// log.info(libVo .getLibType() == 1 ? "准备写入人像设备code={}" : "准备写入工服设备code={}", vo.getEqpNo());
//
// UvModel.UvSystemInfo systemInfo = new UvModel.UvSystemInfo();
// systemInfo.setAccount(vo.getEqpAccount());
// systemInfo.setPassword(vo.getEqpPwd());
// systemInfo.setIp(vo.getEqpIp());
// systemInfo.setPort(vo.getEqpPort());
//
// // 获取宇视线上库ID
// SisLibDeviceRefBo refBo = new SisLibDeviceRefBo();
// refBo.setEqpId(eqpId);
// refBo.setLibId(libVo.getId());
// List<SisLibDeviceRefVo> refVo = sisLibDeviceRefService.queryList(refBo);
// Assert.notNull(refVo, "系统库与设备库关联关系不存在libId:{},eqpId:{}", libVo.getId(), eqpId);
// eqp_lib_id = refVo.get(0).getEqpLibId();
//
// if (libVo.getLibType() == 1) {
// // 宇视添加人像
// UvModel.AddPersonParams addPersonParams = new UvModel.AddPersonParams();
// addPersonParams.setPerson_name(imgVo.getImgName());
// addPersonParams.setImage_base64(base64Helper(imageByte));
// addPersonParams.setLib_id(Math.toIntExact(eqp_lib_id));
// addPersonParams.setSex(imgVo.getSex());
// addPersonParams.setEmail(imgVo.getEmail());
// addPersonParams.setTel(imgVo.getTel());
// addPersonParams.setCertificate_type(imgVo.getCertificateType());
// addPersonParams.setCertificate_no(imgVo.getCertificateNo());
// addPersonParams.setBirth_date(imgVo.getBirthDate());
// // 发起请求获取响应
// UvModel.AddPersonResult addResult = unViewAiBoxApi.addPerson(systemInfo, addPersonParams);
// eqp_lib_img_id = addResult.getPerson_id();
//
// } else {
// UvModel.WorkClothesInfo addResult = unViewAiBoxApi.addWorkClothes(systemInfo, Math.toIntExact(eqp_lib_id), base64Helper(imageByte));
// eqp_lib_img_id = addResult.getWorkclothes_id();
// }
// Assert.notNull(eqp_lib_img_id, "图片上传宇视盒子失败");
// log.info("图片上传宇视盒子完成eqp_lib_img_id = {}", eqp_lib_img_id);
//
// SisLibDeviceImgRefBo ref = new SisLibDeviceImgRefBo();
// ref.setLibId(libVo.getId());
// ref.setImgId(imgVo.getId());
// ref.setEqpId(eqpId);
// ref.setEqpLibId(eqp_lib_id);
// ref.setEqpLibImgId(eqp_lib_img_id.longValue());
// Boolean insert = sisLibDeviceImgRefService.insertByBo(ref);
// Assert.isTrue(insert, "写入图片关联关系表失败!");
//
// }
// }
// log.info("图片开始下发完成!");
//
// log.info("开始写入E8平台图片{}、门禁:{}", bo.getImgIds(), bo.getAcIds());
// for (SisPersonLibImgVo imgVo : imgList) {
// byte[] imageByte = remoteFileService.downloadToByteArray(imgVo.getImgOssId());
// Assert.notNull(imageByte, "图片下载失败");
//
// log.info("E8平台上传图片{}", imgVo.getId());
// String url = e8VouchService.uploadFace(imageByte);
// Assert.notNull(url, "E8平台上传图片失败");
// log.info("E8平台上传图片完成!");
//
// log.info("E8平台发行凭证");
// IssueVoucherReq req = new IssueVoucherReq();
// // 34普通用户卡
// req.setCardType(34);
// // 70人脸凭证
// req.setVoucherType(70);
// // TODO 临时默认人员
// req.setPersonID(539696740646981L);
// req.setTxtData(url);
// Long vId = e8VouchService.issueVoucher(req);
// Assert.notNull(vId, "E8平台发行凭证失败");
// log.info("E8平台发行凭证完成!");
//
// log.info("E8平台授权凭证");
// // 查询E8授权门列表
// List<AuthDoorDeviceFindRes> authDoorList = e8DoorDeviceService.getPageAuthDoorDeviceList();
// Assert.notEmpty(authDoorList, "E8平台授权门列表为空");
//
// // E8 授权列表
// List<CustomerAuthAddReq.AuthGroupData> authList = new ArrayList<>(acList.size());
// // 授权记录
// List<SisAuthRecord> recordList = new ArrayList<>(acList.size());
// // E8授权门
// AuthDoorDeviceFindRes authDoor = null;
// for (SisAccessControlVo sisAccessControlVo : acList) {
// if (sisAccessControlVo.getControlType() != 1 && sisAccessControlVo.getAccessType() != 2) {
//
// // 通过门禁ID匹配授权门
// authDoor = authDoorList.stream().filter(item -> item.getDeviceId() == Long.parseLong(sisAccessControlVo.getOutCode())).findFirst().orElse(null);
//
// if (authDoor != null) {
// CustomerAuthAddReq.AuthGroupData door = new CustomerAuthAddReq.AuthGroupData();
// door.setType(0);
// door.setGatewayType(1);
// // E8授权传入ID为门ID非门禁ID
// door.setId(authDoor.getId());
// authList.add(door);
//
// SisAuthRecord authRecord = new SisAuthRecord();
// authRecord.setDoorId(authDoor.getId());
// authRecord.setDeviceId(authDoor.getDeviceId());
// authRecord.setLibId(imgVo.getLibId());
// authRecord.setImgId(imgVo.getId());
// authRecord.setAcId(sisAccessControlVo.getId());
// recordList.add(authRecord);
// }
// }
// }
//
// CustomerAuthAddReq authReq = new CustomerAuthAddReq();
// authReq.setAuthType(0);
// authReq.setScheduleId(1L);
// authReq.setPersonIds(Collections.singletonList(539696740646981L));
// authReq.setStartTime("2025-06-25 11: 23: 39");
// authReq.setEndTime("2025-07-25 11: 23: 39");
// authReq.setAuthData(authList);
// Boolean auth = e8AccessControlService.addCustomerAuth(authReq);
// Assert.isTrue(auth, "E8平台授权失败");
// log.info("E8平台授权完成!");
// boolean insert = baseMapper.insertBatch(recordList);
// Assert.isTrue(insert, "写入E8关联关系表失败!");
// }
// log.info("写入E8平台完成!");
//
// } catch (Exception e) {
// throw new RuntimeException(e.getMessage());
// }
//
// return true;
return true;
}
if (CollUtil.isEmpty(bo.getDeviceIds())) {
return false;
}
public String base64Helper(byte[] imageByte) throws IOException {
// 1. 将字节数组解码为BufferedImage对象
ByteArrayInputStream bis = new ByteArrayInputStream(imageByte);
// 每次授权先删除上一次授权信息
deleteByLibId(bo.getLibId());
// 2. 将图片重新编码为JPG格式的字节数组
ByteArrayOutputStream bos = new ByteArrayOutputStream();
// 过滤不是设备的节点数据
// 门禁设备
List<SisAccessControlVo> acVoList = accessControlService.queryListByIds(bo.getDeviceIds());
// 电梯设备
List<SisElevatorInfoVo> eleVoList = elevatorInfoService.queryListByIds(bo.getDeviceIds());
if (CollUtil.isEmpty(acVoList) || CollUtil.isEmpty(eleVoList)) {
return false;
}
ImgUtil.convert(bis, "jpg", bos);
// 批量写入授权数据
boolean flag = false;
log.info("开始写入门禁授权记录acIds{}", acVoList);
for (SisAccessControlVo ac : acVoList) {
SisAuthRecord authRecord = new SisAuthRecord();
byte[] jpgBytes = bos.toByteArray();
authRecord.setDeviceType(1);
authRecord.setDeviceId(ac.getId());
authRecord.setLibId(bo.getLibId());
flag = baseMapper.insert(authRecord) > 0;
Assert.isTrue(flag, "写入门禁授权记录失败!");
}
log.info("写入门禁授权记录完成");
// 3. 将JPG字节数组转为Base64字符串
return Base64.getEncoder().encodeToString(jpgBytes);
}
log.info("开始写入电梯授权记录eleIds{}", eleVoList);
for (SisElevatorInfoVo ele : eleVoList) {
SisAuthRecord authRecord = new SisAuthRecord();
@Override
public Boolean singleAuth(SingleAuthRecordBo bo) {
return null;
authRecord.setDeviceType(2);
authRecord.setLibId(bo.getLibId());
authRecord.setDeviceId(ele.getElevatorId());
flag = baseMapper.insert(authRecord) > 0;
Assert.isTrue(flag, "写入电梯授权记录失败!");
}
log.info("写入电梯授权记录完成");
return flag;
}
/**
@@ -331,45 +179,99 @@ public class SisAuthRecordServiceImpl implements ISisAuthRecordService {
return baseMapper.deleteByIds(ids) > 0;
}
@Override
public SisAuthRecordVo checkAuth(Integer personId, Long accessControlId) {
return baseMapper.checkAuth(personId, accessControlId);
}
@Override
public Boolean deleteByLibId(Long libId) {
LambdaQueryWrapper<SisAuthRecord> lqw = Wrappers.lambdaQuery();
lqw.eq(SisAuthRecord::getLibId, libId);
return baseMapper.delete(lqw) > 0;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean authLib(AuthLibBo bo) {
if (CollUtil.isEmpty(bo.getDeviceIds())) {
return false;
}
// 每次授权先删除上一次授权信息
deleteByLibId(bo.getLibId());
// 过滤点不是设备的节点数据
List<SisDeviceManage> ls = deviceManageService.queryByIds(bo.getDeviceIds());
if (CollUtil.isEmpty(ls)) {
return false;
}
// 批量写入授权数据
List<SisAuthRecord> list = ls.stream().map(item -> {
SisAuthRecord authRecord = new SisAuthRecord();
authRecord.setDeviceId(item.getId());
authRecord.setLibId(bo.getLibId());
return authRecord;
}).toList();
return baseMapper.insertBatch(list);
}
/**
* 查询库id授权的设备
*
* @param libId 人像库id
* @return List<SisAuthRecord>
*/
@Override
public List<SisAuthRecord> queryAuthDevice(String libId) {
LambdaQueryWrapper<SisAuthRecord> lqw = Wrappers.lambdaQuery();
lqw.eq(SisAuthRecord::getLibId, libId);
return baseMapper.selectList(lqw);
}
/**
* 根据人像库id删除授权记录
*
* @param libId 人像库id
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean deleteByLibId(Long libId) {
LambdaQueryWrapper<SisAuthRecord> lqw = Wrappers.lambdaQuery();
lqw.eq(SisAuthRecord::getLibId, libId);
return baseMapper.delete(lqw) > 0;
}
/**
* 查询所有可授权设备树
*
* @return List<TreeNode < Long>>
*/
@Override
public List<TreeNode<Long>> authDeviceTree() {
// 暂时将所有数据放入写死的根节点中
TreeNode<Long> root = new TreeNode<>();
root.setLevel(0);
root.setCode(0L);
root.setParentCode(-1L);
root.setLabel("授权设备");
// 创建门禁设备父节点
TreeNode<Long> accessNode = new TreeNode<>();
accessNode.setLevel(1);
accessNode.setCode(1L);
accessNode.setParentCode(0L);
accessNode.setLabel("门禁设备");
// 创建电梯父节点
TreeNode<Long> elevatorNode = new TreeNode<>();
elevatorNode.setLevel(1);
elevatorNode.setCode(2L);
elevatorNode.setParentCode(0L);
elevatorNode.setLabel("电梯设备");
List<SisAccessControlVo> acVoList = accessControlService.queryList(new SisAccessControlBo());
List<SisElevatorInfoVo> eleVoList = elevatorInfoService.queryList(new SisElevatorInfoBo());
List<TreeNode<Long>> acChildrenList = acVoList.stream().map(item -> {
TreeNode<Long> node = new TreeNode<>();
node.setLevel(2);
node.setCode(item.getId());
node.setParentCode(1L);
node.setLabel(item.getAccessName());
return node;
}).toList();
List<TreeNode<Long>> eleChildrenList = eleVoList.stream().map(item -> {
TreeNode<Long> node = new TreeNode<>();
node.setLevel(2);
node.setCode(item.getElevatorId());
node.setParentCode(2L);
node.setLabel(item.getElevatorName());
return node;
}).toList();
// 将子节点列表分别添加到对应的父节点
accessNode.setChildren(acChildrenList);
elevatorNode.setChildren(eleChildrenList);
// 最后将两个父节点添加到根节点
root.setChildren(List.of(accessNode, elevatorNode));
return List.of(root);
}
/**
* 根据人脸比对ID返回授权记录
*
* @param personId 人脸比对ID
*/
@Override
public List<SisAuthRecordVo> checkAuth(Long personId) {
return baseMapper.checkAuth(personId);
}
}

View File

@@ -138,10 +138,10 @@ public class SisDeviceBindRefServiceImpl implements ISisDeviceBindRefService {
}
@Override
public SisDeviceBindRef queryByDeviceIp(String ipcAddr) {
public List<SisDeviceBindRefVo> queryByDeviceIp(String ipcAddr) {
LambdaQueryWrapper<SisDeviceBindRef> lqw = new LambdaQueryWrapper<>();
lqw.eq(SisDeviceBindRef::getDeviceIp, ipcAddr);
return baseMapper.selectOne(lqw);
return baseMapper.selectVoList(lqw);
}
@Override

View File

@@ -0,0 +1,145 @@
package org.dromara.sis.service.impl;
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.springframework.stereotype.Service;
import org.dromara.sis.domain.bo.SisElevatorFloorRefBo;
import org.dromara.sis.domain.vo.SisElevatorFloorRefVo;
import org.dromara.sis.domain.SisElevatorFloorRef;
import org.dromara.sis.mapper.SisElevatorFloorRefMapper;
import org.dromara.sis.service.ISisElevatorFloorRefService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* 电梯⇄楼层关联Service业务层处理
*
* @author lsm
* @date 2025-07-15
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class SisElevatorFloorRefServiceImpl implements ISisElevatorFloorRefService {
private final SisElevatorFloorRefMapper baseMapper;
/**
* 查询电梯⇄楼层关联
*
* @param id 主键
* @return 电梯⇄楼层关联
*/
@Override
public SisElevatorFloorRefVo queryById(Long id) {
return baseMapper.selectVoById(id);
}
/**
* 分页查询电梯⇄楼层关联列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 电梯⇄楼层关联分页列表
*/
@Override
public TableDataInfo<SisElevatorFloorRefVo> queryPageList(SisElevatorFloorRefBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<SisElevatorFloorRef> lqw = buildQueryWrapper(bo);
Page<SisElevatorFloorRefVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的电梯⇄楼层关联列表
*
* @param bo 查询条件
* @return 电梯⇄楼层关联列表
*/
@Override
public List<SisElevatorFloorRefVo> queryList(SisElevatorFloorRefBo bo) {
LambdaQueryWrapper<SisElevatorFloorRef> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<SisElevatorFloorRef> buildQueryWrapper(SisElevatorFloorRefBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<SisElevatorFloorRef> lqw = Wrappers.lambdaQuery();
lqw.orderByAsc(SisElevatorFloorRef::getId);
lqw.eq(bo.getElevatorId() != null, SisElevatorFloorRef::getElevatorId, bo.getElevatorId());
lqw.eq(bo.getLayerNum() != null, SisElevatorFloorRef::getLayerNum, bo.getLayerNum());
return lqw;
}
/**
* 新增电梯⇄楼层关联
*
* @param bo 电梯⇄楼层关联
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(SisElevatorFloorRefBo bo) {
SisElevatorFloorRef add = MapstructUtils.convert(bo, SisElevatorFloorRef.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改电梯⇄楼层关联
*
* @param bo 电梯⇄楼层关联
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(SisElevatorFloorRefBo bo) {
SisElevatorFloorRef update = MapstructUtils.convert(bo, SisElevatorFloorRef.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(SisElevatorFloorRef entity) {
//TODO 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除电梯⇄楼层关联信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
/**
* 根据电梯id获取电梯⇄楼层关联信息
*
* @param elevatorId 电梯id
*/
@Override
public List<SisElevatorFloorRefVo> queryByElevatorId(Long elevatorId) {
LambdaQueryWrapper<SisElevatorFloorRef> lqw = Wrappers.lambdaQuery();
lqw.eq(SisElevatorFloorRef::getElevatorId, elevatorId);
return baseMapper.selectVoList(lqw);
}
}

View File

@@ -253,4 +253,15 @@ public class SisElevatorInfoServiceImpl implements ISisElevatorInfoService {
public List<SisElevatorInfoVo> queryAll() {
return baseMapper.selectVoList();
}
/**
* 根据查询列表
*
* @param ids 电梯id
* @return 列表
*/
@Override
public List<SisElevatorInfoVo> queryListByIds(Collection<Long> ids){
return baseMapper.selectVoByIds(ids);
}
}

View File

@@ -0,0 +1,149 @@
package org.dromara.sis.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
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.springframework.stereotype.Service;
import org.dromara.sis.domain.bo.SisFloorInfoBo;
import org.dromara.sis.domain.vo.SisFloorInfoVo;
import org.dromara.sis.domain.SisFloorInfo;
import org.dromara.sis.mapper.SisFloorInfoMapper;
import org.dromara.sis.service.ISisFloorInfoService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* 建筑物楼层信息Service业务层处理
*
* @author lsm
* @since 2025-07-15
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class SisFloorInfoServiceImpl implements ISisFloorInfoService {
private final SisFloorInfoMapper baseMapper;
/**
* 查询建筑物楼层信息
*
* @param floorId 主键
* @return 建筑物楼层信息
*/
@Override
public SisFloorInfoVo queryById(Long floorId){
return baseMapper.selectVoById(floorId);
}
/**
* 分页查询建筑物楼层信息列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 建筑物楼层信息分页列表
*/
@Override
public TableDataInfo<SisFloorInfoVo> queryPageList(SisFloorInfoBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<SisFloorInfo> lqw = buildQueryWrapper(bo);
Page<SisFloorInfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的建筑物楼层信息列表
*
* @param bo 查询条件
* @return 建筑物楼层信息列表
*/
@Override
public List<SisFloorInfoVo> queryList(SisFloorInfoBo bo) {
LambdaQueryWrapper<SisFloorInfo> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<SisFloorInfo> buildQueryWrapper(SisFloorInfoBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<SisFloorInfo> lqw = Wrappers.lambdaQuery();
lqw.orderByAsc(SisFloorInfo::getFloorId);
lqw.eq(bo.getMinLayer() != null, SisFloorInfo::getMinLayer, bo.getMinLayer());
lqw.eq(bo.getMaxLayer() != null, SisFloorInfo::getMaxLayer, bo.getMaxLayer());
lqw.eq(bo.getBuildingId() != null, SisFloorInfo::getBuildingId, bo.getBuildingId());
lqw.eq(bo.getCommunityId() != null, SisFloorInfo::getCommunityId, bo.getCommunityId());
return lqw;
}
/**
* 新增建筑物楼层信息
*
* @param bo 建筑物楼层信息
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(SisFloorInfoBo bo) {
SisFloorInfo add = MapstructUtils.convert(bo, SisFloorInfo.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setFloorId(add.getFloorId());
}
return flag;
}
/**
* 修改建筑物楼层信息
*
* @param bo 建筑物楼层信息
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(SisFloorInfoBo bo) {
SisFloorInfo update = MapstructUtils.convert(bo, SisFloorInfo.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(SisFloorInfo entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除建筑物楼层信息信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
/**
* 根据建筑ID返回楼层信息
*
* @param buildingId 建筑ID
* @return 楼层信息
*/
@Override
public SisFloorInfoVo queryByBuildingId(Long buildingId){
LambdaQueryWrapper<SisFloorInfo> qw = new LambdaQueryWrapper<>();
qw.eq(SisFloorInfo::getBuildingId, buildingId);
return baseMapper.selectVoOne(qw);
}
}

View File

@@ -0,0 +1,148 @@
package org.dromara.sis.service.impl;
import cn.hutool.core.lang.Assert;
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.springframework.stereotype.Service;
import org.dromara.sis.domain.bo.SisLibImgRefBo;
import org.dromara.sis.domain.vo.SisLibImgRefVo;
import org.dromara.sis.domain.SisLibImgRef;
import org.dromara.sis.mapper.SisLibImgRefMapper;
import org.dromara.sis.service.ISisLibImgRefService;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* 人像库-人像图片关联Service业务层处理
*
* @author lsm
* @since 2025-07-14
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class SisLibImgRefServiceImpl implements ISisLibImgRefService {
private final SisLibImgRefMapper baseMapper;
/**
* 查询人像库-人像图片关联
*
* @param libId 主键
* @return 人像库-人像图片关联
*/
@Override
public SisLibImgRefVo queryById(Long libId){
return baseMapper.selectVoById(libId);
}
/**
* 分页查询人像库-人像图片关联列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 人像库-人像图片关联分页列表
*/
@Override
public TableDataInfo<SisLibImgRefVo> queryPageList(SisLibImgRefBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<SisLibImgRef> lqw = buildQueryWrapper(bo);
Page<SisLibImgRefVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的人像库-人像图片关联列表
*
* @param bo 查询条件
* @return 人像库-人像图片关联列表
*/
@Override
public List<SisLibImgRefVo> queryList(SisLibImgRefBo bo) {
LambdaQueryWrapper<SisLibImgRef> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<SisLibImgRef> buildQueryWrapper(SisLibImgRefBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<SisLibImgRef> lqw = Wrappers.lambdaQuery();
lqw.orderByAsc(SisLibImgRef::getLibId);
lqw.orderByAsc(SisLibImgRef::getImgId);
return lqw;
}
/**
* 新增人像库-人像图片关联
*
* @param bo 人像库-人像图片关联
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(SisLibImgRefBo bo) {
SisLibImgRef add = MapstructUtils.convert(bo, SisLibImgRef.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setLibId(add.getLibId());
}
return flag;
}
/**
* 修改人像库-人像图片关联
*
* @param bo 人像库-人像图片关联
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(SisLibImgRefBo bo) {
SisLibImgRef update = MapstructUtils.convert(bo, SisLibImgRef.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(SisLibImgRef entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除人像库-人像图片关联信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
/**
* 批量添加人像库-人像图片关联
*
* @param refs 待添加的关联信息
* @return boolean
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean addBatch(List<SisLibImgRef> refs){
boolean flag = baseMapper.insertBatch(refs);
Assert.isTrue( flag, "批量添加人像库-人像图片关联失败");
return flag;
}
}

View File

@@ -14,7 +14,9 @@ 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.resource.api.RemoteFileService;
import org.dromara.sis.domain.SisLibImgRef;
import org.dromara.sis.domain.SisPersonLibImg;
import org.dromara.sis.domain.bo.SisLibImgRefBo;
import org.dromara.sis.domain.bo.SisPersonLibImgBo;
import org.dromara.sis.domain.vo.*;
import org.dromara.sis.mapper.SisPersonLibImgMapper;
@@ -38,7 +40,9 @@ import java.util.*;
public class SisPersonLibImgServiceImpl implements ISisPersonLibImgService {
private final SisPersonLibImgMapper baseMapper;
private final HuaWeiBoxApi huaWeiBoxApi;
private final ISisLibImgRefService sisLibImgRefService;
@DubboReference
private final RemoteFileService remoteFileService;
@@ -51,7 +55,15 @@ public class SisPersonLibImgServiceImpl implements ISisPersonLibImgService {
*/
@Override
public SisPersonLibImgVo queryById(Long id) {
return baseMapper.selectVoById(id);
SisLibImgRefBo refBo = new SisLibImgRefBo();
refBo.setImgId(id);
List<SisLibImgRefVo> refs = sisLibImgRefService.queryList(refBo);
Collection<Long> refIds = refs.stream().map(SisLibImgRefVo::getId).toList();
SisPersonLibImgVo vo = new SisPersonLibImgVo();
vo.setLibIds(refIds);
return vo;
}
/**
@@ -84,7 +96,6 @@ public class SisPersonLibImgServiceImpl implements ISisPersonLibImgService {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<SisPersonLibImg> lqw = Wrappers.lambdaQuery();
lqw.orderByAsc(SisPersonLibImg::getId);
lqw.eq(bo.getLibId() != null, SisPersonLibImg::getLibId, bo.getLibId());
lqw.like(StringUtils.isNotBlank(bo.getImgName()), SisPersonLibImg::getImgName, bo.getImgName());
lqw.eq(bo.getImgOssId() != null, SisPersonLibImg::getImgOssId, bo.getImgOssId());
lqw.eq(bo.getSex() != null, SisPersonLibImg::getSex, bo.getSex());
@@ -130,7 +141,20 @@ public class SisPersonLibImgServiceImpl implements ISisPersonLibImgService {
add.setRemoteImgId(pId);
flag = baseMapper.insert(add) > 0;
Assert.isTrue(flag, "新增失败");
Assert.isTrue(flag, "新增人像失败");
log.info("开始写入人像⇄人像库关联表");
List<SisLibImgRef> refs = new ArrayList<>();
for (Long libId : bo.getLibIds()) {
SisLibImgRef ref = new SisLibImgRef();
ref.setLibId(libId);
ref.setImgId(add.getId());
refs.add(ref);
}
Boolean refFlag = sisLibImgRefService.addBatch(refs);
Assert.isTrue(refFlag, "写入人像⇄人像库关联表失败!");
log.info("写入人像⇄人像库关联表完成");
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}

View File

@@ -5,10 +5,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<mapper namespace="org.dromara.sis.mapper.SisAuthRecordMapper">
<select id="checkAuth" resultType="org.dromara.sis.domain.vo.SisAuthRecordVo">
SELECT a.*
FROM sis_auth_record a
LEFT JOIN sis_lib_device_img_ref b ON a.lib_id = b.lib_id AND a.img_id = b.img_id
WHERE a.ac_id = #{accessControlId}
AND b.eqp_lib_img_id = #{personId}
SELECT
device_type,
device_id
FROM sis_auth_record sar
WHERE EXISTS (
SELECT 1
FROM sis_person_lib_img a
INNER JOIN sis_lib_img_ref b ON a.id = b.img_id
WHERE a.remote_img_id = #{personId}
AND b.lib_id = sar.lib_id -- 关联主表
)
</select>
</mapper>