diff --git a/ruoyi-api/sis-api/src/main/java/org/dromara/sis/api/RemoteSisAuth.java b/ruoyi-api/sis-api/src/main/java/org/dromara/sis/api/RemoteSisAuth.java deleted file mode 100644 index d177bcc8..00000000 --- a/ruoyi-api/sis-api/src/main/java/org/dromara/sis/api/RemoteSisAuth.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.dromara.sis.api; - -import org.dromara.sis.api.domain.RemotePersonAuth; - -import java.util.Collection; - -/** - * @author lsm - * @apiNote RemoteSisAuth - * @since 2025/7/24 - */ -public interface RemoteSisAuth { - - Boolean personAuth(RemotePersonAuth personAuth); - - Boolean updatePersonAuth(RemotePersonAuth personAuth); - - Boolean deletePersonAuth(Collection personId, Collection e8Ids); -} diff --git a/ruoyi-api/sis-api/src/main/java/org/dromara/sis/api/RemoteSisAuthService.java b/ruoyi-api/sis-api/src/main/java/org/dromara/sis/api/RemoteSisAuthService.java new file mode 100644 index 00000000..254ee655 --- /dev/null +++ b/ruoyi-api/sis-api/src/main/java/org/dromara/sis/api/RemoteSisAuthService.java @@ -0,0 +1,75 @@ +package org.dromara.sis.api; + +import org.dromara.sis.api.domain.RemotePersonAuth; + +import java.util.Collection; + +/** + * @author lsm + * @apiNote RemoteSisAuthService + * @since 2025/7/24 + */ +public interface RemoteSisAuthService { + + /** + * 人员授权 + * + * @param personAuth 人员授权信息 + * @return Boolean + */ + Boolean personAuth(RemotePersonAuth personAuth); + + /** + * 删除人员授权信息 + * + * @param personIds 入驻员工ids + * @param e8Ids e8平台人员id是 + * @return Boolean + */ + Boolean deletePersonAuth(Collection personIds, Collection e8Ids); + + /** + * 查询人员授权信息 + * + * @param authGroupId 权限组id + * @param personId 人员id + * @return Boolean + */ + Boolean queryPersonAuth(Long authGroupId, Long personId); + + /** + * 通过MD5,查询图片id + * + * @param imgMd5 图片MD5 + * @return Long + */ + Long queryImgIdByImgMd5(String imgMd5); + + /** + * 图片写入华为盒子 + * + * @param person 人员信息 + * @param imgByte 图片字节数组 + * @return Long 图片id + */ + Long syncHuaweiBox(RemotePersonAuth person, byte[] imgByte); + + /** + * 更新人像信息 + * + * @param id 入驻员工id + * @param huaweiBoxId 华为盒子id + * @param md5Str 图片MD5 + * @return Boolean + */ + Boolean updateImgByPersonId(Long id, Long huaweiBoxId, String md5Str); + + /** + * 图片写入E8平台 + * + * @param person 人员信息 + * @param imgByte 图片字节数组 + * @return Long e8平台id + */ + Long syncE8Plat(RemotePersonAuth person, byte[] imgByte); +} diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ResidentPersonServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ResidentPersonServiceImpl.java index 417c7cfc..b3aed1ea 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ResidentPersonServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ResidentPersonServiceImpl.java @@ -13,8 +13,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.extern.slf4j.Slf4j; import org.dromara.property.domain.vo.ResidentUnitVo; import org.dromara.property.service.IResidentUnitService; -import org.dromara.sis.api.RemoteSisAuth; -import org.dromara.sis.api.domain.RemotePersonAuth; +import org.dromara.sis.api.RemoteSisAuthService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; @@ -30,7 +29,6 @@ import java.util.List; import java.util.Map; import java.util.Collection; import java.util.Objects; -import java.util.stream.Collectors; /** * 入驻员工Service业务层处理 @@ -50,7 +48,7 @@ public class ResidentPersonServiceImpl implements IResidentPersonService { private IResidentUnitService residentUnitService; @DubboReference - private RemoteSisAuth remoteSisAuth; + private RemoteSisAuthService remoteSisAuthService; /** * 查询入驻员工 @@ -159,7 +157,7 @@ public class ResidentPersonServiceImpl implements IResidentPersonService { if (flag && e8Id != null) { log.info("开始修改授权记录, {}", bo.getUserName()); // 先删除,定时任务增加 - Boolean auth = remoteSisAuth.deletePersonAuth(List.of(update.getId()), List.of(e8Id)); + Boolean auth = remoteSisAuthService.deletePersonAuth(List.of(update.getId()), List.of(e8Id)); Assert.isTrue(auth, "修改授权记录失败!"); } @@ -217,7 +215,7 @@ public class ResidentPersonServiceImpl implements IResidentPersonService { .filter(Objects::nonNull) .toList(); if (!e8Ids.isEmpty()) { - boolean auth = remoteSisAuth.deletePersonAuth(ids, e8Ids); + boolean auth = remoteSisAuthService.deletePersonAuth(ids, e8Ids); Assert.isTrue(auth, "删除授权记录失败!"); } } diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/dubbo/RemoteSisAuthImpl.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/dubbo/RemoteSisAuthImpl.java deleted file mode 100644 index 6f96bf02..00000000 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/dubbo/RemoteSisAuthImpl.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.dromara.sis.dubbo; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.apache.dubbo.config.annotation.DubboService; -import org.dromara.sis.api.RemoteSisAuth; -import org.dromara.sis.api.domain.RemotePersonAuth; -import org.dromara.sis.service.ISisAuthRecordService; - -import java.util.Collection; - -/** - * @author lsm - * @apiNote RemoteSisAuthImpl - * @since 2025/7/24 - */ -@Slf4j -@DubboService -@RequiredArgsConstructor -public class RemoteSisAuthImpl implements RemoteSisAuth { - - private final ISisAuthRecordService sisAuthRecordService; - - @Override - public Boolean personAuth(RemotePersonAuth personAuth) { - return sisAuthRecordService.insertByPerson(personAuth); - } - - @Override - public Boolean updatePersonAuth(RemotePersonAuth personAuth) { - return sisAuthRecordService.updateByBo(personAuth); - } - - @Override - public Boolean deletePersonAuth(Collection ids, Collection e8Ids) { - return sisAuthRecordService.deleteByPersonIds(ids, e8Ids); - } -} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/dubbo/RemoteSisAuthServiceImpl.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/dubbo/RemoteSisAuthServiceImpl.java new file mode 100644 index 00000000..4418cf1f --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/dubbo/RemoteSisAuthServiceImpl.java @@ -0,0 +1,222 @@ +package org.dromara.sis.dubbo; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.IdUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.dubbo.config.annotation.DubboService; +import org.dromara.common.core.constant.CodePrefixConstants; +import org.dromara.sis.api.RemoteSisAuthService; +import org.dromara.sis.api.domain.RemotePersonAuth; +import org.dromara.sis.domain.vo.SisAccessControlVo; +import org.dromara.sis.domain.vo.SisAuthGroupRefVo; +import org.dromara.sis.domain.vo.SisAuthRecordVo; +import org.dromara.sis.domain.vo.SisPersonLibImgVo; +import org.dromara.sis.sdk.e8.E8PlatformApi; +import org.dromara.sis.sdk.e8.domain.accessControl.req.CustomerAuthAddReq; +import org.dromara.sis.sdk.e8.domain.custom.req.CustomAddReq; +import org.dromara.sis.sdk.e8.domain.voucher.req.IssueVoucherReq; +import org.dromara.sis.sdk.huawei.HuaWeiBoxApi; +import org.dromara.sis.sdk.huawei.domain.AddHWPersonReq; +import org.dromara.sis.service.ISisAccessControlService; +import org.dromara.sis.service.ISisAuthGroupRefService; +import org.dromara.sis.service.ISisAuthRecordService; +import org.dromara.sis.service.ISisPersonLibImgService; + +import java.util.ArrayList; +import java.util.Base64; +import java.util.Collection; +import java.util.List; + +/** + * @author lsm + * @apiNote RemoteSisAuthServiceImpl + * @since 2025/7/24 + */ +@Slf4j +@DubboService +@RequiredArgsConstructor +public class RemoteSisAuthServiceImpl implements RemoteSisAuthService { + + private final HuaWeiBoxApi huaWeiBoxApi; + private final E8PlatformApi e8PlatformApi; + private final ISisAuthRecordService sisAuthRecordService; + private final ISisPersonLibImgService sisPersonLibImgService; + private final ISisAuthGroupRefService sisAuthGroupRefService; + private final ISisAccessControlService sisAccessControlService; + + /** + * 人员授权 + * + * @param personAuth 人员授权信息 + * @return Boolean + */ + @Override + public Boolean personAuth(RemotePersonAuth personAuth) { + return sisAuthRecordService.insertByPerson(personAuth); + } + + /** + * 删除人员授权信息 + * + * @param ids 入驻员工ids + * @param e8Ids e8平台人员id是 + * @return Boolean + */ + @Override + public Boolean deletePersonAuth(Collection ids, Collection e8Ids) { + return sisAuthRecordService.deleteByPersonIds(ids, e8Ids); + } + + + /** + * 查询人员授权信息 + * + * @param authGroupId 权限组id + * @param personId 人员id + * @return Boolean + */ + @Override + public Boolean queryPersonAuth(Long authGroupId, Long personId) { + SisAuthRecordVo vo = sisAuthRecordService.queryByGroupIdAndPersonId(authGroupId, personId); + return vo != null; + } + + /** + * 通过MD5,查询图片id + * + * @param imgMd5 图片MD5 + * @return Long + */ + @Override + public Long queryImgIdByImgMd5(String imgMd5) { + SisPersonLibImgVo vo = sisPersonLibImgService.queryByImgMd5(imgMd5); + return vo != null ? vo.getId() : null; + } + + /** + * 图片写入华为盒子 + * + * @param person 人员信息 + * @param imgByte 图片字节数组 + * @return Long 图片id + */ + @Override + public Long syncHuaweiBox(RemotePersonAuth person, byte[] imgByte) { + Long pId; + try { + AddHWPersonReq req = new AddHWPersonReq(); + req.setIndex(CodePrefixConstants.PERSON_LIB_IMAGE_CODE_PREFIX + IdUtil.getSnowflakeNextIdStr()); + req.setName(person.getName()); + req.setGender(person.getSex() == 1 ? "0" : person.getSex() == 2 ? "1" : "-1"); + + ArrayList pictures = new ArrayList<>(); + pictures.add(Base64.getEncoder().encodeToString(imgByte)); + req.setPictures(pictures); + + pId = huaWeiBoxApi.addPerson(List.of(req)); + } catch (Exception e) { + return null; + } + return pId; + } + + /** + * 更新人像信息 + * + * @param id 入驻员工id + * @param huaweiBoxId 华为盒子id + * @param md5Str 图片MD5 + * @return Boolean + */ + @Override + public Boolean updateImgByPersonId(Long id, Long huaweiBoxId, String md5Str) { + return sisPersonLibImgService.updateByPersonId(id, huaweiBoxId, md5Str); + } + + /** + * 图片写入E8平台 + * + * @param person 人员信息 + * @param imgByte 图片字节数组 + * @return Long e8平台id + */ + @Override + public Long syncE8Plat(RemotePersonAuth person, byte[] imgByte) { + // 初始化步进器 + int count = 0; + Long e8Id; + + try { + log.info("e8平台上传照片"); + String e8ImgUrl = e8PlatformApi.uploadFace(imgByte); + Assert.notNull(e8ImgUrl, "图片上传E8平台失败"); + log.info("e8平台上传照片完成"); + count++; // 图片上传完成步进器+1 + + log.info("e8同步新建人员"); + CustomAddReq req = new CustomAddReq(); + req.setName(person.getName()); + req.setGender(person.getSex() != 1 ? 0 : 1); + e8Id = e8PlatformApi.addCustomer(req).getId(); + Assert.notNull(e8Id, "e8同步新建人员失败"); + log.info("e8同步新建人员完成"); + count++; // 新增人员完成步进器+1 + + log.info("e8平台开始发行凭证"); + IssueVoucherReq voucherReq = new IssueVoucherReq(); + voucherReq.setVoucherType(70); + voucherReq.setPersonID(e8Id); + voucherReq.setTxtData(e8ImgUrl); + voucherReq.setCardType(34); + Long voucherId = e8PlatformApi.issueVoucher(voucherReq); + Assert.notNull(voucherId, "e8平台发行凭证失败"); + log.info("e8平台发行凭证成功"); + count++; // 发行凭证完成步进器+1 + + // 获取门禁 + List refVos = sisAuthGroupRefService.queryListByGroupId(person.getAuthGroupId()); + Collection deviceIds = refVos.stream().filter(ref -> ref.getDeviceType() == 1).map(SisAuthGroupRefVo::getDeviceId).toList(); + if (CollUtil.isNotEmpty(deviceIds)) { + // 初始化赋值 + CustomerAuthAddReq authReq = new CustomerAuthAddReq(); + authReq.setPersonIds(List.of(e8Id)); + authReq.setStartTime(DateUtil.format(person.getAuthBegDate(), "yyyy-MM-dd HH:mm:ss")); + authReq.setEndTime(DateUtil.format(person.getAuthEndDate(), "yyyy-MM-dd HH:mm:ss")); + List list = new ArrayList<>(); + SisAccessControlVo accessControlVo; + for (Long deviceId : deviceIds) { + accessControlVo = sisAccessControlService.queryById(deviceId); + CustomerAuthAddReq.AuthGroupData authData = new CustomerAuthAddReq.AuthGroupData(); + authData.setId(Long.parseLong(accessControlVo.getOutDoorCode())); + authData.setType(0); + authData.setGatewayType(1); + list.add(authData); + } + authReq.setAuthData(list); + + log.info("e8平台开始授权"); + Boolean flag = e8PlatformApi.addCustomerAuth(authReq); + Assert.isTrue(flag, "E8平台授权失败!"); + log.info("E8平台授权完成!"); + count++; // 授权完成步进器+1 + } + } catch (Exception e) { + return null; + } + + if (count == 4) { + // 授权完成,返回e8平台人员Id + return e8Id; + } else if (count >= 2 && count < 4) { + // 人员新建完成,授权失败,删除人员 + e8PlatformApi.deleteCustomer(e8Id); + return null; + } else { + return null; + } + } + +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/task/AuthSyncTask.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/task/AuthSyncTask.java deleted file mode 100644 index 2b1941d2..00000000 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/task/AuthSyncTask.java +++ /dev/null @@ -1,317 +0,0 @@ -package org.dromara.sis.task; - -import cn.dev33.satoken.context.mock.SaTokenContextMockUtil; -import cn.dev33.satoken.stp.StpUtil; -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.date.DateUtil; -import cn.hutool.core.lang.Assert; -import cn.hutool.core.util.IdUtil; -import cn.hutool.core.util.ObjectUtil; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.apache.dubbo.config.annotation.DubboReference; -import org.dromara.common.core.constant.CodePrefixConstants; -import org.dromara.property.api.RemoteResidentPersonService; -import org.dromara.property.api.domain.vo.RemoteResidentPersonVo; -import org.dromara.resource.api.RemoteFileService; -import org.dromara.sis.api.domain.RemotePersonAuth; -import org.dromara.sis.domain.vo.*; -import org.dromara.sis.sdk.e8.E8PlatformApi; -import org.dromara.sis.sdk.e8.domain.accessControl.req.CustomerAuthAddReq; -import org.dromara.sis.sdk.e8.domain.custom.req.CustomAddReq; -import org.dromara.sis.sdk.e8.domain.voucher.req.IssueVoucherReq; -import org.dromara.sis.sdk.huawei.HuaWeiBoxApi; -import org.dromara.sis.sdk.huawei.domain.AddHWPersonReq; -import org.dromara.sis.service.ISisAccessControlService; -import org.dromara.sis.service.ISisAuthGroupRefService; -import org.dromara.sis.service.ISisAuthRecordService; -import org.dromara.sis.service.ISisPersonLibImgService; -import org.springframework.context.annotation.Configuration; -import org.springframework.scheduling.annotation.EnableScheduling; -import org.springframework.scheduling.annotation.Scheduled; - -import java.security.MessageDigest; -import java.util.*; -import java.util.concurrent.atomic.AtomicReference; - -/** - * @author lsm - * @apiNote AuthSyncTask - * @since 2025/7/26 - */ -@Slf4j -@Configuration -@EnableScheduling -@RequiredArgsConstructor -public class AuthSyncTask { - - @DubboReference - private RemoteFileService remoteFileService; - - @DubboReference - private RemoteResidentPersonService remoteResidentPersonService; - - private final HuaWeiBoxApi huaWeiBoxApi; - private final E8PlatformApi e8PlatformApi; - private final ISisAuthRecordService sisAuthRecordService; - private final ISisPersonLibImgService sisPersonLibImgService; - private final ISisAuthGroupRefService sisAuthGroupRefService; - private final ISisAccessControlService sisAccessControlService; - - /** - * 每两分钟执行一次 - */ -// @Scheduled(cron = "0 */5 * * * ?") - public void autoAuth() { - AtomicReference> unAuthPersonRef = new AtomicReference<>(new ArrayList<>()); - AtomicReference imgByteRef = new AtomicReference<>(new byte[0]); - - // 需要先设置模拟上下文 - SaTokenContextMockUtil.setMockContext(() -> { - // 模拟登录 - StpUtil.login(1); - unAuthPersonRef.set(remoteResidentPersonService.queryUnAuthPerson()); - List unAuthPerson = unAuthPersonRef.get(); - - try { - if (CollUtil.isNotEmpty(unAuthPerson)) { - for (RemoteResidentPersonVo person : unAuthPerson) { - log.info("开始定时授权:{}----{}", person.getName(), person.getId()); - - // 判断是否已存在授权 - SisAuthRecordVo authRecord = sisAuthRecordService.queryByGroupIdAndPersonId(person.getAuthGroupId(), person.getId()); - if (ObjectUtil.isEmpty(authRecord)) { - log.info("无授权记录:{}----{}", person.getName(), person.getId()); - this.syncAuthRecord(person); - - imgByteRef.set(remoteFileService.downloadToByteArray(Long.parseLong(person.getOssId()))); - // 读取人像 - byte[] imgByte = imgByteRef.get(); - if (imgByte == null) { - log.info("下载图片失败:{}-----{}", person.getName(), person.getId()); - sisAuthRecordService.deleteByPersonIds(List.of(person.getId()), new ArrayList<>()); - continue; - } - -// String nowMd5 = this.calculateMD5(imgByte); -// SisPersonLibImgVo imgVo = sisPersonLibImgService.queryByImgMd5(nowMd5); -// -// Long huaweiId; -// Boolean update; -// if (ObjectUtil.isEmpty(imgVo)) { -// // 写入华为盒子 -// huaweiId = syncHuaweiBox(person, imgByte); -// } else { -// if (imgVo.getRemoteImgId() == null) { -// huaweiId = syncHuaweiBox(person, imgByte); -// } else { -// huaweiId = imgVo.getRemoteImgId(); -// } -// } -// -// if (huaweiId == null){ -// log.info("华为盒子人像上传失败:{}-----{}", person.getName(), person.getId()); -// sisAuthRecordService.deleteByPersonIds(List.of(person.getId()), new ArrayList<>()); -// continue; -// } -// -// // 更新人像信息huaweiBoxId -// update = sisPersonLibImgService.updateByPersonId(person.getId(), huaweiId, nowMd5); -// if (!update) { -// log.info("更新人像信息失败:{}-----{}", person.getName(), person.getId()); -// sisAuthRecordService.deleteByPersonIds(List.of(person.getId()), new ArrayList<>()); -// continue; -// } - - // 同步E8平台 - Long e8Id = syncE8Plat(person, imgByte); - if (e8Id == null) { - log.info("E8平台授权失败:{}-----{}", person.getName(), person.getId()); - sisAuthRecordService.deleteByPersonIds(List.of(person.getId()), new ArrayList<>()); - continue; - } - - // 更新入驻员工E8平台id - remoteResidentPersonService.updateE8Id(person.getId(), e8Id); - } else { - log.info("已存在授权记录:{}-----{}", person.getName(), person.getId()); - } - } - } else { - log.info("无待授权人员"); - } - } catch (Exception e) { - throw new RuntimeException(e); - } - }); - } - - /** - * 补录授权记录 - * - * @param person bean - */ - private void syncAuthRecord(RemoteResidentPersonVo person) { - log.info("开始补录授权记录、人像信息"); - RemotePersonAuth personAuth = new RemotePersonAuth(); - personAuth.setId(person.getId()); - personAuth.setOssId(person.getOssId()); - personAuth.setName(person.getName()); - personAuth.setPhone(person.getPhone()); - personAuth.setSex(person.getGender().intValue()); - personAuth.setIdCardNumber(person.getIdCard()); - personAuth.setAuthGroupId(person.getAuthGroupId()); - personAuth.setAuthBegDate(person.getAuthBegDate()); - personAuth.setAuthEndDate(person.getAuthEndDate()); - sisAuthRecordService.insertByPerson(personAuth); - log.info("补录授权记录、人像信息完成"); - } - - /** - * 同步华为盒子 - * - * @param vo bean - * @param imgByte 图片字节 - * @return Long - */ - private Long syncHuaweiBox(RemoteResidentPersonVo vo, byte[] imgByte) { - - Long pId; - try { - log.info("开始写入华为平台"); - AddHWPersonReq req = new AddHWPersonReq(); - req.setIndex(CodePrefixConstants.PERSON_LIB_IMAGE_CODE_PREFIX + IdUtil.getSnowflakeNextIdStr()); - req.setName(vo.getName()); - req.setGender(vo.getGender() == 1L ? "0" : vo.getGender() == 2L ? "1" : "-1"); - req.setCredentialType("0"); - req.setCredentialNumber(vo.getIdCard()); - - ArrayList pictures = new ArrayList<>(); - pictures.add(Base64.getEncoder().encodeToString(imgByte)); - req.setPictures(pictures); - - pId = huaWeiBoxApi.addPerson(List.of(req)); - Assert.notNull(pId, "调用华为盒子新增图片失败"); - log.info("写入华为盒子完成,pId={}", pId); - } catch (Exception e) { - return null; - } - return pId; - } - - /** - * 同步E8平台 - * - * @param vo bean - * @param imgByte 图片字节 - * @return Long - */ - private Long syncE8Plat(RemoteResidentPersonVo vo, byte[] imgByte) { - // 初始化步进器 - int count = 0; - Long e8Id = null; - - try { - log.info("e8平台上传照片"); - String e8ImgUrl = e8PlatformApi.uploadFace(imgByte); - Assert.notNull(e8ImgUrl, "图片上传E8平台失败"); - log.info("e8平台上传照片完成"); - count++; // 图片上传完成步进器+1 - - log.info("e8同步新建人员"); - CustomAddReq req = new CustomAddReq(); - req.setName(vo.getName()); - req.setGender(vo.getGender() != 1L ? 0 : 1); - req.setIdentityType(0); - req.setIdentityNo(vo.getIdCard()); - e8Id = e8PlatformApi.addCustomer(req).getId(); - Assert.notNull(e8Id, "e8同步新建人员失败"); - log.info("e8同步新建人员完成"); - count++; // 新增人员完成步进器+1 - - - log.info("e8平台开始发行凭证"); - IssueVoucherReq voucherReq = new IssueVoucherReq(); - voucherReq.setVoucherType(70); - voucherReq.setPersonID(e8Id); - voucherReq.setTxtData(e8ImgUrl); - voucherReq.setCardType(34); - Long voucherId = e8PlatformApi.issueVoucher(voucherReq); - Assert.notNull(voucherId, "e8平台发行凭证失败"); - log.info("e8平台发行凭证成功"); - count++; // 发行凭证完成步进器+1 - - // 获取门禁 - List refVos = sisAuthGroupRefService.queryListByGroupId(vo.getAuthGroupId()); - Collection deviceIds = refVos.stream().filter(ref -> ref.getDeviceType() == 1).map(SisAuthGroupRefVo::getDeviceId).toList(); - if (CollUtil.isNotEmpty(deviceIds)) { - // 初始化赋值 - CustomerAuthAddReq authReq = new CustomerAuthAddReq(); - authReq.setPersonIds(List.of(e8Id)); - authReq.setStartTime(DateUtil.format(vo.getAuthBegDate(), "yyyy-MM-dd HH:mm:ss")); - authReq.setEndTime(DateUtil.format(vo.getAuthEndDate(), "yyyy-MM-dd HH:mm:ss")); - List list = new ArrayList<>(); - SisAccessControlVo accessControlVo; - for (Long deviceId : deviceIds) { - accessControlVo = sisAccessControlService.queryById(deviceId); - CustomerAuthAddReq.AuthGroupData authData = new CustomerAuthAddReq.AuthGroupData(); - authData.setId(Long.parseLong(accessControlVo.getOutDoorCode())); - authData.setType(0); - authData.setGatewayType(1); - list.add(authData); - } - authReq.setAuthData(list); - - log.info("e8平台开始授权"); - Boolean flag = e8PlatformApi.addCustomerAuth(authReq); - Assert.isTrue(flag, "E8平台授权失败!"); - log.info("E8平台授权完成!"); - count++; // 授权完成步进器+1 - } - } catch (Exception e) { - return null; - } - - if (count == 4) { - // 授权完成,返回e8平台人员Id - return e8Id; - } else if (count >= 2 && count < 4) { - // 人员新建完成,授权失败,删除人员 - e8PlatformApi.deleteCustomer(e8Id); - return null; - } else { - return null; - } - } - - /** - * 直接计算字节数组的MD5值 - * - * @param data 图片的字节数组 - * @return 32位小写MD5字符串 - */ - public String calculateMD5(byte[] data) throws Exception { - if (data == null) { - throw new IllegalArgumentException("输入数据不能为null"); - } - - MessageDigest md = MessageDigest.getInstance("MD5"); - md.update(data); - return bytesToHex(md.digest()); - } - - /** - * 字节数组转十六进制字符串 - * - * @param bytes 字节数组 - * @return 32位十六进制字符串 - */ - private String bytesToHex(byte[] bytes) { - StringBuilder sb = new StringBuilder(); - for (byte b : bytes) { - // %02x 表示两位小写十六进制,不足两位补0 - sb.append(String.format("%02x", b)); - } - return sb.toString(); - } -} diff --git a/ruoyi-modules/ruoyi-job/pom.xml b/ruoyi-modules/ruoyi-job/pom.xml index 4ebe1809..1802fa4e 100644 --- a/ruoyi-modules/ruoyi-job/pom.xml +++ b/ruoyi-modules/ruoyi-job/pom.xml @@ -83,6 +83,12 @@ 2.4.0 + + org.dromara + ruoyi-api-resource + 2.4.0 + + diff --git a/ruoyi-modules/ruoyi-job/src/main/java/org/dromara/job/snailjob/sis/AuthSyncTask.java b/ruoyi-modules/ruoyi-job/src/main/java/org/dromara/job/snailjob/sis/AuthSyncTask.java deleted file mode 100644 index a860bfed..00000000 --- a/ruoyi-modules/ruoyi-job/src/main/java/org/dromara/job/snailjob/sis/AuthSyncTask.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.dromara.job.snailjob.sis; - -import com.aizuda.snailjob.client.job.core.annotation.JobExecutor; -import com.aizuda.snailjob.client.job.core.dto.JobArgs; -import com.aizuda.snailjob.client.model.ExecuteResult; -import org.apache.dubbo.config.annotation.DubboReference; -import org.dromara.property.api.RemoteResidentPersonService; -import org.dromara.property.api.domain.vo.RemoteResidentPersonVo; -import org.springframework.stereotype.Component; - -import java.util.List; - -/** - * @author lsm - * @apiNote AuthSyncTask - * @since 2025/8/1 - */ -@Component -@JobExecutor(name = "authSyncTask") -public class AuthSyncTask { - - @DubboReference - private RemoteResidentPersonService remoteResidentPersonService; - - public ExecuteResult jobExecute(JobArgs jobArgs) throws InterruptedException { - List unAuthPerson = remoteResidentPersonService.queryUnAuthPerson(); - return ExecuteResult.success(unAuthPerson); - } -} diff --git a/ruoyi-modules/ruoyi-job/src/main/java/org/dromara/job/snailjob/sis/SyncGrantAuthTask.java b/ruoyi-modules/ruoyi-job/src/main/java/org/dromara/job/snailjob/sis/SyncGrantAuthTask.java new file mode 100644 index 00000000..a021f170 --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/org/dromara/job/snailjob/sis/SyncGrantAuthTask.java @@ -0,0 +1,243 @@ +package org.dromara.job.snailjob.sis; + +import cn.dev33.satoken.context.mock.SaTokenContextMockUtil; +import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.core.collection.CollUtil; +import com.aizuda.snailjob.client.job.core.annotation.JobExecutor; +import com.aizuda.snailjob.client.job.core.dto.JobArgs; +import com.aizuda.snailjob.client.model.ExecuteResult; +import lombok.extern.slf4j.Slf4j; +import org.apache.dubbo.config.annotation.DubboReference; +import org.dromara.property.api.RemoteResidentPersonService; +import org.dromara.property.api.domain.vo.RemoteResidentPersonVo; +import org.dromara.resource.api.RemoteFileService; +import org.dromara.sis.api.RemoteSisAuthService; +import org.dromara.sis.api.domain.RemotePersonAuth; +import org.springframework.stereotype.Component; + +import java.security.MessageDigest; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; + +/** + * @author lsm + * @apiNote SyncGrantAuthTask + * @since 2025/8/1 + */ +@Slf4j +@Component +@JobExecutor(name = "syncGrantAuthTask") +public class SyncGrantAuthTask { + + @DubboReference + private RemoteFileService remoteFileService; + + @DubboReference + private RemoteSisAuthService remoteSisAuthService; + + @DubboReference + private RemoteResidentPersonService remoteResidentPersonService; + + public ExecuteResult jobExecute(JobArgs jobArgs) throws InterruptedException { + AtomicReference> unAuthPersonRef = new AtomicReference<>(new ArrayList<>()); + AtomicReference imgByteRef = new AtomicReference<>(new byte[0]); + + // 需要先设置模拟上下文 + SaTokenContextMockUtil.setMockContext(() -> { + // 模拟登录 + StpUtil.login(1); + unAuthPersonRef.set(remoteResidentPersonService.queryUnAuthPerson()); + List unAuthPerson = unAuthPersonRef.get(); + + try { + if (CollUtil.isNotEmpty(unAuthPerson)) { + for (RemoteResidentPersonVo person : unAuthPerson) { + log.info("开始定时授权:{}----{}", person.getName(), person.getId()); + + // 判断是否存在授权 + Boolean auth = remoteSisAuthService.queryPersonAuth(person.getAuthGroupId(), person.getId()); + if (!auth) { + log.info("无授权记录:{}----{}", person.getName(), person.getId()); + + // 补录授权记录、人像信息 + Boolean flag = syncAuthRecord(person); + if (!flag) { + log.info("补录授权记录、人像信息失败:{}----{}", person.getName(), person.getId()); + continue; + } + + // 下载人像 + byte[] imgByte; + try { + imgByteRef.set(remoteFileService.downloadToByteArray(Long.parseLong(person.getOssId()))); + imgByte = imgByteRef.get(); + } catch (Exception e) { + log.info("下载图片失败:{}----{}", person.getName(), person.getId()); + remoteSisAuthService.deletePersonAuth(List.of(person.getId()), new ArrayList<>()); + continue; + } + + // 计算图片MD5 + String nowMd5 = calculateMD5(imgByte); + // 通过MD5查询相同图片 + Long remoteId = remoteSisAuthService.queryImgIdByImgMd5(nowMd5); + + Long huaweiId; + if (remoteId == null) { + // 当前本地人像信息不存在相同照片,直接上传华为盒子 + huaweiId = syncHuaweiBox(person, imgByte); + } else { + huaweiId = remoteId; + } + + if (huaweiId == null) { + log.info("华为盒子人像上传失败:{}-----{}", person.getName(), person.getId()); + remoteSisAuthService.deletePersonAuth(List.of(person.getId()), new ArrayList<>()); + continue; + } + + Boolean update = false; + try { + update = remoteSisAuthService.updateImgByPersonId(person.getId(), huaweiId, nowMd5); + } catch (Exception e) { + remoteSisAuthService.deletePersonAuth(List.of(person.getId()), new ArrayList<>()); + } + + if (!update) { + log.info("更新人像信息失败:{}-----{}", person.getName(), person.getId()); + remoteSisAuthService.deletePersonAuth(List.of(person.getId()), new ArrayList<>()); + continue; + } + + // 同步人像到E8平台 + Long e8Id = syncE8Plat(person, imgByte); + if (e8Id == null) { + log.info("同步人像到E8平台失败:{}-----{}", person.getName(), person.getId()); + remoteSisAuthService.deletePersonAuth(List.of(person.getId()), new ArrayList<>()); + continue; + } + + // 更新入驻员工E8平台id + remoteResidentPersonService.updateE8Id(person.getId(), e8Id); + } else { + // 存在授权记录,为了避免重复授权,删除授权记录 + remoteSisAuthService.deletePersonAuth(List.of(person.getId()), new ArrayList<>()); + } + } + } else { + log.info("无待授权人员"); + } + } catch (Exception e) { + log.info("同步授权异常"); + throw new RuntimeException(e); + } + }); + + + return ExecuteResult.success(); + } + + /** + * 补录授权记录 + * + * @param person bean + */ + private Boolean syncAuthRecord(RemoteResidentPersonVo person) { + log.info("开始补录授权记录、人像信息:{}----{}", person.getName(), person.getId()); + RemotePersonAuth personAuth = getRemotePersonAuth(person); + + Boolean flag; + try { + flag = remoteSisAuthService.personAuth(personAuth); + if (flag) { + log.info("补录授权记录、人像信息完成:{}----{}", person.getName(), person.getId()); + } + } catch (Exception e) { + return false; + } + return flag; + } + + /** + * 实体类转换 + */ + private RemotePersonAuth getRemotePersonAuth(RemoteResidentPersonVo person) { + RemotePersonAuth personAuth = new RemotePersonAuth(); + personAuth.setId(person.getId()); + personAuth.setOssId(person.getOssId()); + personAuth.setName(person.getName()); + personAuth.setPhone(person.getPhone()); + personAuth.setSex(person.getGender().intValue()); + personAuth.setIdCardNumber(person.getIdCard()); + personAuth.setAuthGroupId(person.getAuthGroupId()); + personAuth.setAuthBegDate(person.getAuthBegDate()); + personAuth.setAuthEndDate(person.getAuthEndDate()); + return personAuth; + } + + /** + * 同步华为盒子 + * + * @param vo bean + * @param imgByte 图片字节 + * @return Long + */ + private Long syncHuaweiBox(RemoteResidentPersonVo vo, byte[] imgByte) { + log.info("开始写入华为盒子"); + RemotePersonAuth personAuth = getRemotePersonAuth(vo); + Long pId = remoteSisAuthService.syncHuaweiBox(personAuth, imgByte); + if (pId != null) { + log.info("写入华为盒子完成,pId={}", pId); + } + return pId; + } + + /** + * 同步E8平台 + * + * @param vo bean + * @param imgByte 图片字节 + * @return Long + */ + private Long syncE8Plat(RemoteResidentPersonVo vo, byte[] imgByte) { + log.info("开始写入E8平台"); + RemotePersonAuth personAuth = getRemotePersonAuth(vo); + Long e8Id = remoteSisAuthService.syncE8Plat(personAuth, imgByte); + if (e8Id != null) { + log.info("写入E8平台完成:e8Id={}", e8Id); + } + return e8Id; + } + + /** + * 直接计算字节数组的MD5值 + * + * @param data 图片的字节数组 + * @return 32位小写MD5字符串 + */ + public String calculateMD5(byte[] data) throws Exception { + if (data == null) { + throw new IllegalArgumentException("输入数据不能为null"); + } + + MessageDigest md = MessageDigest.getInstance("MD5"); + md.update(data); + return bytesToHex(md.digest()); + } + + /** + * 字节数组转十六进制字符串 + * + * @param bytes 字节数组 + * @return 32位十六进制字符串 + */ + private String bytesToHex(byte[] bytes) { + StringBuilder sb = new StringBuilder(); + for (byte b : bytes) { + // %02x 表示两位小写十六进制,不足两位补0 + sb.append(String.format("%02x", b)); + } + return sb.toString(); + } +}