From e3e26f46c14fe724e2d25eb88fa8b4104a9e0e1f Mon Sep 17 00:00:00 2001 From: zcxlsm Date: Tue, 29 Jul 2025 02:04:15 +0800 Subject: [PATCH 1/9] =?UTF-8?q?feat(property):=20-=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=85=A5=E9=A9=BB=E5=91=98=E5=B7=A5=E5=AF=BC=E5=85=A5=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=EF=BC=8C=E6=94=AF=E6=8C=81=E5=AF=BC=E5=85=A5=E5=91=98?= =?UTF-8?q?=E5=B7=A5=E4=BF=A1=E6=81=AF=E5=92=8C=E4=BA=BA=E8=84=B8=E6=95=B0?= =?UTF-8?q?=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ResidentPersonController.java | 46 +++- .../domain/vo/ResidentPersonImportVo.java | 75 +++++++ .../ResidentPersonImportListener.java | 141 ++++++++++++ .../impl/ResidentPersonServiceImpl.java | 7 +- .../property/utils/UploadFaceUtil.java | 205 ++++++++++++++++++ .../sis/sdk/hik/calback/HikAlarmCallBack.java | 9 +- .../sdk/huawei/domain/FinaHWPersonReq.java | 2 +- .../AuthTimer.java => task/AuthSyncTask.java} | 6 +- 8 files changed, 478 insertions(+), 13 deletions(-) create mode 100644 ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ResidentPersonImportVo.java create mode 100644 ruoyi-modules/Property/src/main/java/org/dromara/property/listener/ResidentPersonImportListener.java create mode 100644 ruoyi-modules/Property/src/main/java/org/dromara/property/utils/UploadFaceUtil.java rename ruoyi-modules/Sis/src/main/java/org/dromara/sis/{config/timer/AuthTimer.java => task/AuthSyncTask.java} (99%) diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/ResidentPersonController.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/ResidentPersonController.java index 83c1670e..8dc6a506 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/ResidentPersonController.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/ResidentPersonController.java @@ -1,11 +1,17 @@ package org.dromara.property.controller; +import java.util.ArrayList; 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.excel.core.ExcelResult; +import org.dromara.property.domain.vo.ResidentPersonImportVo; +import org.dromara.property.listener.ResidentPersonImportListener; +import org.dromara.property.utils.UploadFaceUtil; +import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; import org.springframework.validation.annotation.Validated; import org.dromara.common.idempotent.annotation.RepeatSubmit; @@ -21,6 +27,7 @@ import org.dromara.property.domain.vo.ResidentPersonVo; import org.dromara.property.domain.bo.ResidentPersonBo; import org.dromara.property.service.IResidentPersonService; import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.springframework.web.multipart.MultipartFile; /** * 入驻员工 @@ -37,6 +44,8 @@ public class ResidentPersonController extends BaseController { private final IResidentPersonService residentPersonService; + private final UploadFaceUtil uploadFaceUtil; + /** * 查询入驻员工列表 */ @@ -65,7 +74,7 @@ public class ResidentPersonController extends BaseController { @SaCheckPermission("property:person:query") @GetMapping("/{id}") public R getInfo(@NotNull(message = "主键不能为空") - @PathVariable("id") Long id) { + @PathVariable("id") Long id) { return R.ok(residentPersonService.queryById(id)); } @@ -103,4 +112,39 @@ public class ResidentPersonController extends BaseController { @PathVariable("ids") Long[] ids) { return toAjax(residentPersonService.deleteWithValidByIds(List.of(ids), true)); } + + /** + * 导入数据 + * + * @param file 导入文件 + * @param updateSupport 是否更新已存在数据 + * @param unitId 单位id + */ + @Log(title = "入驻员工", businessType = BusinessType.IMPORT) + @SaCheckPermission("property:person:import") + @PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + public R importData(@RequestPart("file") MultipartFile file, boolean updateSupport, Long unitId) throws Exception { + ExcelResult result = ExcelUtil.importExcel(file.getInputStream(), ResidentPersonImportVo.class, new ResidentPersonImportListener(updateSupport, unitId)); + return R.ok(result.getAnalysis()); + } + + /** + * 获取导入模板 + */ + @PostMapping("/importTemplate") + public void importTemplate(HttpServletResponse response) { + ExcelUtil.exportExcel(new ArrayList<>(), "入驻员工", ResidentPersonImportVo.class, response); + } + + /** + * 导入人脸数据 + * + * @param file 导入文件 + * @param unitId 单位ID + */ + @PostMapping(value = "/importFace", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + public R importFace(@RequestPart("file") MultipartFile file, Long unitId) { + uploadFaceUtil.processFaceZip(file, unitId); + return R.ok(); + } } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ResidentPersonImportVo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ResidentPersonImportVo.java new file mode 100644 index 00000000..b849480e --- /dev/null +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ResidentPersonImportVo.java @@ -0,0 +1,75 @@ +package org.dromara.property.domain.vo; + +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.dromara.common.excel.annotation.ExcelDictFormat; +import org.dromara.common.excel.convert.ExcelDictConvert; +import org.dromara.property.domain.ResidentPerson; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + + +/** + * 入驻员工视图对象 resident_person + * + * @author mocheng + * @since 2025-06-19 + */ +@Data +@NoArgsConstructor +public class ResidentPersonImportVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + + /** + * 用户名称 + */ + @ExcelProperty(value = "用户名称") + private String userName; + + /** + * 联系电话 + */ + @ExcelProperty(value = "联系电话") + private String phone; + + /** + * 用户性别 + */ + @ExcelProperty(value = "性别", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "sys_user_sex") + private String gender; + + /** + * 证件号 + */ + @ExcelProperty(value = "证件号") + private String idCard; + + /** + * 邮箱 + */ + @ExcelProperty(value = "邮箱") + private String email; + + + /** + * 车牌号码 + */ + @ExcelProperty(value = "车牌号码") + private String carNumber; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + +} diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/listener/ResidentPersonImportListener.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/listener/ResidentPersonImportListener.java new file mode 100644 index 00000000..678fcf45 --- /dev/null +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/listener/ResidentPersonImportListener.java @@ -0,0 +1,141 @@ +package org.dromara.property.listener; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.http.HtmlUtil; +import cn.idev.excel.context.AnalysisContext; +import cn.idev.excel.event.AnalysisEventListener; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.ConstraintViolationException; +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.exception.ServiceException; +import org.dromara.common.core.utils.SpringUtils; +import org.dromara.common.core.utils.StreamUtils; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.core.utils.ValidatorUtils; +import org.dromara.common.excel.core.ExcelListener; +import org.dromara.common.excel.core.ExcelResult; +import org.dromara.common.satoken.utils.LoginHelper; +import org.dromara.property.domain.bo.ResidentPersonBo; +import org.dromara.property.domain.vo.ResidentPersonImportVo; +import org.dromara.property.domain.vo.ResidentPersonVo; +import org.dromara.property.domain.vo.ResidentUnitVo; +import org.dromara.property.service.IResidentPersonService; +import org.dromara.property.service.IResidentUnitService; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * @author lsm + * @apiNote ResidentPersonImportListener + * @since 2025/7/28 + */ +@Slf4j +public class ResidentPersonImportListener extends AnalysisEventListener implements ExcelListener { + + private final IResidentPersonService residentPersonService; + + private final IResidentUnitService residentUnitService; + + private final Boolean isUpdateSupport; + + private final Long unitId; + + private int successNum = 0; + private int failureNum = 0; + private final StringBuilder successMsg = new StringBuilder(); + private final StringBuilder failureMsg = new StringBuilder(); + + public ResidentPersonImportListener(Boolean isUpdateSupport, Long unitId) { + this.residentPersonService = SpringUtils.getBean(IResidentPersonService.class); + this.residentUnitService = SpringUtils.getBean(IResidentUnitService.class); + this.isUpdateSupport = isUpdateSupport; + this.unitId = unitId; + } + + @Override + public void invoke(ResidentPersonImportVo personVo, AnalysisContext context) { + ResidentUnitVo unitVo = residentUnitService.queryById(unitId); + List list = new ArrayList<>(); + // 判断证件号是否为空 + if (StringUtils.isEmpty(personVo.getIdCard())) { + failureNum++; + failureMsg.append("
").append(failureNum).append("、账号 ").append(personVo.getUserName()).append(" 证件号不能为空!"); + } else { + ResidentPersonBo personBo = new ResidentPersonBo(); + personBo.setUnitId(unitId); + personBo.setIdCard(personVo.getIdCard()); + list = residentPersonService.queryList(personBo); + } + try { + if (list.isEmpty()) { // 判断当前单位是否已存在该用户 + ResidentPersonBo bo = BeanUtil.toBean(personVo, ResidentPersonBo.class); + ValidatorUtils.validate(bo); + bo.setState(1L); + bo.setUnitId(unitId); + bo.setTime(new Date()); + bo.setUnitName(unitVo.getName()); + bo.setAuthGroupId(unitVo.getAuthGroupId()); + bo.setAuthBegDate(unitVo.getAuthBegDate()); + bo.setAuthEndDate(unitVo.getAuthEndDate()); + residentPersonService.insertByBo(bo); + successNum++; + successMsg.append("
").append(successNum).append("、账号 ").append(bo.getUserName()).append(" 导入成功"); + } else if (isUpdateSupport) { + Long id = list.get(0).getUserId(); + ResidentPersonBo bo = BeanUtil.toBean(personVo, ResidentPersonBo.class); + bo.setId(id); + ValidatorUtils.validate(bo); + bo.setUpdateBy(LoginHelper.getUserId()); + residentPersonService.updateByBo(bo); + successNum++; + successMsg.append("
").append(successNum).append("、账号 ").append(bo.getUserName()).append(" 更新成功"); + } else { + failureNum++; + failureMsg.append("
").append(failureNum).append("、账号 ").append(list.get(0).getUserName()).append(" 已存在"); + } + + } catch (Exception e) { + failureNum++; + String msg = "
" + failureNum + "、账号 " + HtmlUtil.cleanHtmlTag(personVo.getUserName()) + " 导入失败:"; + String message = e.getMessage(); + if (e instanceof ConstraintViolationException cvException) { + message = StreamUtils.join(cvException.getConstraintViolations(), ConstraintViolation::getMessage, ", "); + } + failureMsg.append(msg).append(message); + } + } + + @Override + public void doAfterAllAnalysed(AnalysisContext context) { + + } + + @Override + public ExcelResult getExcelResult() { + return new ExcelResult<>() { + @Override + public String getAnalysis() { + if (failureNum > 0) { + failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:"); + throw new ServiceException(failureMsg.toString()); + } else { + successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:"); + } + return successMsg.toString(); + } + + @Override + public List getList() { + return null; + } + + @Override + public List getErrorList() { + return null; + } + + }; + } +} 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 db0a92ae..762ad13b 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 @@ -121,10 +121,13 @@ public class ResidentPersonServiceImpl implements IResidentPersonService { // 首次入驻新用户权限组默认使用公司权限 ResidentUnitVo ruVo = residentUnitService.queryById(bo.getUnitId()); add.setAuthGroupId(ruVo.getAuthGroupId()); + add.setAuthBegDate(ruVo.getAuthBegDate()); + add.setAuthEndDate(ruVo.getAuthEndDate()); boolean flag = baseMapper.insert(add) > 0; Assert.isTrue(flag, "员工入驻失败!"); - if (flag) { + // 存在图片时,才同步授权 + if (flag && add.getImg() != null) { log.info("开始写入授权记录, {}", bo.getUserName()); RemotePersonAuth personAuth = new RemotePersonAuth(); personAuth.setId(add.getId()); @@ -190,7 +193,7 @@ public class ResidentPersonServiceImpl implements IResidentPersonService { public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { if (isValid) { LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); - lqw.eq(ResidentPerson::getId, ids); + lqw.in(ResidentPerson::getId, ids); List list = baseMapper.selectVoList(lqw); boolean hasEnabled = list.stream() diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/utils/UploadFaceUtil.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/utils/UploadFaceUtil.java new file mode 100644 index 00000000..c98d5989 --- /dev/null +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/utils/UploadFaceUtil.java @@ -0,0 +1,205 @@ +package org.dromara.property.utils; + +import cn.hutool.core.bean.BeanUtil; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.apache.dubbo.config.annotation.DubboReference; +import org.dromara.property.domain.bo.ResidentPersonBo; +import org.dromara.property.domain.vo.ResidentPersonVo; +import org.dromara.property.service.IResidentPersonService; +import org.dromara.resource.api.RemoteFileService; +import org.dromara.resource.api.domain.RemoteFile; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +/** + * @author lsm + * @apiNote UploadFaceUtil + * @since 2025/7/29 + */ +@Slf4j +@Service +public class UploadFaceUtil { + + @DubboReference + private RemoteFileService remoteFileService; + + @Resource + private IResidentPersonService residentPersonService; + + // 安全配置参数(实际项目中可以从配置文件读取) + private static final int MAX_TOTAL_SIZE = 50 * 1024 * 1024; // 50MB 最大解压总大小 + private static final int MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB 最大单个文件大小 + private static final int MAX_FILE_COUNT = 30; // 最大文件数量 + + private static final Map CONTENT_TYPE_MAP = new HashMap<>(); + static { + CONTENT_TYPE_MAP.put("jpg", "image/jpeg"); + CONTENT_TYPE_MAP.put("jpeg", "image/jpeg"); + CONTENT_TYPE_MAP.put("png", "image/png"); + CONTENT_TYPE_MAP.put("gif", "image/gif"); + } + + // 统计信息 + private int totalFiles = 0; + private int processedFiles = 0; + private int successUploads = 0; + private int failedUploads = 0; + + public void processFaceZip(MultipartFile zipFile, Long unitId) { + // 重置统计信息 + resetStats(); + + try (ZipInputStream zis = new ZipInputStream(zipFile.getInputStream())) { + ZipEntry entry; + byte[] buffer = new byte[8192]; // 8KB缓冲区 + long totalExtractedSize = 0; + int fileCount = 0; + + while ((entry = zis.getNextEntry()) != null) { + // 跳过目录 + if (entry.isDirectory()) { + zis.closeEntry(); + continue; + } + + // 1. 文件数量检查 + if (++fileCount > MAX_FILE_COUNT) { + throw new SecurityException("ZIP炸弹防护:文件数量超过限制 (" + MAX_FILE_COUNT + ")"); + } + + // 2. 单个文件大小检查 + long entrySize = entry.getSize(); + if (entrySize > MAX_FILE_SIZE) { + throw new SecurityException("ZIP炸弹防护:文件 '" + entry.getName() + + "' 大小超过限制 (" + formatSize(MAX_FILE_SIZE) + ")"); + } + + // 3. 总大小检查 + if (entrySize != -1) { // 有些ZIP实现可能返回-1 + if (totalExtractedSize + entrySize > MAX_TOTAL_SIZE) { + throw new SecurityException("ZIP炸弹防护:解压总大小超过限制 (" + + formatSize(MAX_TOTAL_SIZE) + ")"); + } + totalExtractedSize += entrySize; + } + + // 4. 文件类型验证 + if (!isImageFile(entry.getName())) { + zis.closeEntry(); + continue; // 跳过非图片文件 + } + + // 获取姓名(移除文件扩展名) + String name = extractName(entry.getName()); + String contentType = getContentType(entry.getName()); + + // 读取图片数据(使用安全方式) + ByteArrayOutputStream bao = new ByteArrayOutputStream(); + int len; + long actualSize = 0; + + // 流式读取并检查实际大小 + while ((len = zis.read(buffer)) > 0) { + // 检查实际读取大小是否超过限制 + actualSize += len; + if (actualSize > MAX_FILE_SIZE) { + throw new SecurityException("ZIP炸弹防护:文件 '" + entry.getName() + + "' 实际大小超过限制 (" + formatSize(MAX_FILE_SIZE) + ")"); + } + + // 检查总大小 + if (totalExtractedSize + actualSize > MAX_TOTAL_SIZE) { + throw new SecurityException("ZIP炸弹防护:解压总大小超过限制 (" + + formatSize(MAX_TOTAL_SIZE) + ")"); + } + + bao.write(buffer, 0, len); + } + + ResidentPersonBo bo = new ResidentPersonBo(); + bo.setUnitId(unitId); + bo.setUserName(name); + List personVos = residentPersonService.queryList(bo); + // 判断当前姓名是否存在入驻单位 + if (personVos.isEmpty()) continue; + + byte[] imageData = bao.toByteArray(); + + RemoteFile remoteFile = remoteFileService.upload(name, name, contentType, imageData); + + personVos.get(0).setImg(remoteFile.getOssId().toString()); + ResidentPersonBo updateBo = BeanUtil.toBean(personVos.get(0), ResidentPersonBo.class); + residentPersonService.updateByBo(updateBo); + + totalFiles++; + + // 关闭当前entry + zis.closeEntry(); + + // 更新处理进度 + processedFiles++; + } + + // 打印统计信息 + printStatistics(); + } catch (Exception e) { + throw new RuntimeException(e); + } + + } + + private void resetStats() { + totalFiles = 0; + processedFiles = 0; + successUploads = 0; + failedUploads = 0; + } + + private void printStatistics() { + System.out.println("\n===== ZIP处理统计 ====="); + System.out.println("总文件数: " + totalFiles); + System.out.println("已处理文件数: " + processedFiles); + System.out.println("成功上传: " + successUploads); + System.out.println("失败上传: " + failedUploads); + System.out.println("======================="); + } + + private String formatSize(long bytes) { + if (bytes < 1024) return bytes + " B"; + int exp = (int) (Math.log(bytes) / Math.log(1024)); + char unit = "KMGTPE".charAt(exp - 1); + return String.format("%.1f %sB", bytes / Math.pow(1024, exp), unit); + } + + private String extractName(String fileName) { + // 移除路径和扩展名(例如 "王五.jpg" -> "王五") + String baseName = new File(fileName).getName(); + int dotIndex = baseName.lastIndexOf('.'); + return (dotIndex == -1) ? baseName : baseName.substring(0, dotIndex); + } + + private boolean isImageFile(String fileName) { + // 检查常见图片扩展名 + String[] imgExtensions = {".jpg", ".jpeg", ".png", ".gif"}; + String lowerName = fileName.toLowerCase(); + for (String ext : imgExtensions) { + if (lowerName.endsWith(ext)) return true; + } + return false; + } + + public String getContentType(String filename) { + String extension = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase(); + return CONTENT_TYPE_MAP.getOrDefault(extension, "application/octet-stream"); + } +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/calback/HikAlarmCallBack.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/calback/HikAlarmCallBack.java index d5097877..8773a9fa 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/calback/HikAlarmCallBack.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/hik/calback/HikAlarmCallBack.java @@ -23,10 +23,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.text.SimpleDateFormat; -import java.util.Collection; -import java.util.Date; -import java.util.List; -import java.util.Objects; +import java.util.*; import static org.dromara.sis.sdk.hik.HCNetSDK.*; @@ -420,8 +417,8 @@ public class HikAlarmCallBack implements HCNetSDK.FMSGCallBack_V31 { // try { // Thread.sleep(10000L); // List 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)); +// for (int i = 0; i < ass.size(); i++) { +// HikApiService.getInstance().controlGateway("192.168.24.188", (i + 1), ass.get(i)); // } // } catch (InterruptedException e) { // throw new RuntimeException(e); diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/huawei/domain/FinaHWPersonReq.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/huawei/domain/FinaHWPersonReq.java index 2073291f..2b87ee75 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/huawei/domain/FinaHWPersonReq.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/huawei/domain/FinaHWPersonReq.java @@ -17,7 +17,7 @@ public class FinaHWPersonReq { /** * 相似度 */ - private String similarityThreshold = "85"; + private String similarityThreshold = "80"; /** * page */ diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/config/timer/AuthTimer.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/task/AuthSyncTask.java similarity index 99% rename from ruoyi-modules/Sis/src/main/java/org/dromara/sis/config/timer/AuthTimer.java rename to ruoyi-modules/Sis/src/main/java/org/dromara/sis/task/AuthSyncTask.java index dfc80dcd..c692e72c 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/config/timer/AuthTimer.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/task/AuthSyncTask.java @@ -1,4 +1,4 @@ -package org.dromara.sis.config.timer; +package org.dromara.sis.task; import cn.dev33.satoken.context.mock.SaTokenContextMockUtil; import cn.dev33.satoken.stp.StpUtil; @@ -35,14 +35,14 @@ import java.util.concurrent.atomic.AtomicReference; /** * @author lsm - * @apiNote AuthTimer + * @apiNote AuthSyncTask * @since 2025/7/26 */ @Slf4j @Configuration @EnableScheduling @RequiredArgsConstructor -public class AuthTimer { +public class AuthSyncTask { @DubboReference private RemoteFileService remoteFileService; From 00b85990f4ae13f77c227abe491091b4e0548430 Mon Sep 17 00:00:00 2001 From: dy <2389062315@qq.com> Date: Tue, 29 Jul 2025 09:37:11 +0800 Subject: [PATCH 2/9] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/AttendanceGroupServiceImpl.java | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceGroupServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceGroupServiceImpl.java index 7a8bb23d..838dbadb 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceGroupServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceGroupServiceImpl.java @@ -1,27 +1,27 @@ package org.dromara.property.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 com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.property.domain.*; +import org.dromara.property.domain.bo.AttendanceGroupBo; import org.dromara.property.domain.constant.StatusConstant; +import org.dromara.property.domain.vo.AttendanceGroupVo; import org.dromara.property.mapper.*; +import org.dromara.property.service.IAttendanceGroupService; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; -import org.dromara.property.domain.bo.AttendanceGroupBo; -import org.dromara.property.domain.vo.AttendanceGroupVo; -import org.dromara.property.service.IAttendanceGroupService; import org.springframework.transaction.annotation.Transactional; +import java.util.Collection; import java.util.List; import java.util.Map; -import java.util.Collection; import java.util.Objects; import static org.dromara.property.domain.constant.StatusConstant.FIXEDSCHEDULE; @@ -47,6 +47,7 @@ public class AttendanceGroupServiceImpl implements IAttendanceGroupService { private final AttendanceScheduleCycleMapper attendanceScheduleCycleMapper; private final AttendanceWeeksetShiftMapper attendanceWeeksetShiftMapper; + private final AttendanceShiftMapper attendanceShiftMapper; /** @@ -171,7 +172,6 @@ public class AttendanceGroupServiceImpl implements IAttendanceGroupService { BeanUtils.copyProperties(weekSet, attendanceWeekSet); attendanceWeekSet.setGroupId(add.getId()); attendanceWeekSet.setDayOfWeek(weekSet.getDayOfWeek()); -// attendanceWeekSet.setShiftId(weekSet.getShiftId()); weekSetMapper.insert(attendanceWeekSet); //查询出周期表的id Long weekSetId = attendanceWeekSet.getId(); @@ -223,7 +223,6 @@ public class AttendanceGroupServiceImpl implements IAttendanceGroupService { } -// insertAttendaanceClockDate(bo); return flag; } @@ -260,17 +259,21 @@ public class AttendanceGroupServiceImpl implements IAttendanceGroupService { //1.固定班制 //取出考勤组id Long groupId = update.getId(); - //根据考勤组id查询出attendance_week_set表中的数据 - List weekSets = weekSetMapper.selectList(Wrappers.lambdaQuery().eq(AttendanceWeekSet::getGroupId, groupId)); - //根据weekSets修改考勤周期表中的数据 - weekSets.forEach( + bo.getWeekSetList().forEach( weekSet -> { + //1.固定班制,修改考勤周期表中的数据 AttendanceWeekSet attendanceWeekSet = new AttendanceWeekSet(); BeanUtils.copyProperties(weekSet, attendanceWeekSet); attendanceWeekSet.setGroupId(update.getId()); attendanceWeekSet.setDayOfWeek(weekSet.getDayOfWeek()); - attendanceWeekSet.setShiftId(weekSet.getShiftId()); - weekSetMapper.updateById(attendanceWeekSet); + weekSetMapper.update(attendanceWeekSet, Wrappers.lambdaQuery().eq(AttendanceWeekSet::getId, weekSet.getId())); + //查询出周期表的id + Long weekSetId = attendanceWeekSet.getId(); + //根据weekSetId修改中间表中的数据 + AttendanceWeeksetShift attendanceWeeksetShift = new AttendanceWeeksetShift(); + attendanceWeeksetShift.setWeekSetId(weekSetId); + attendanceWeeksetShift.setShiftId(weekSet.getShiftId()); + attendanceWeeksetShiftMapper.update(attendanceWeeksetShift, Wrappers.lambdaQuery().eq(AttendanceWeeksetShift::getWeekSetId, weekSetId)); } ); From bff00b7b4a90d588cf3dc652296b634dfd5692e9 Mon Sep 17 00:00:00 2001 From: dy <2389062315@qq.com> Date: Tue, 29 Jul 2025 11:06:29 +0800 Subject: [PATCH 3/9] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=8E=92=E7=8F=AD?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/AttendanceArrangement.java | 4 +- .../domain/bo/AttendanceArrangementBo.java | 15 +- .../domain/constant/StatusConstant.java | 6 + .../domain/vo/AttendanceArrangementVo.java | 6 +- .../AttendanceArrangementServiceImpl.java | 129 +++++++++++------- 5 files changed, 100 insertions(+), 60 deletions(-) diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/AttendanceArrangement.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/AttendanceArrangement.java index c5143b1c..fb83467d 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/AttendanceArrangement.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/AttendanceArrangement.java @@ -55,12 +55,12 @@ public class AttendanceArrangement extends TenantEntity { /** * 开始日期 */ - private LocalDate startDate; + private Date startDate; /** * 结束日期(仅date_type=3时有效) */ - private LocalDate endDate; + private Date endDate; /** * 状态:0-未生效,1-已生效 diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/AttendanceArrangementBo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/AttendanceArrangementBo.java index 99cdc10b..f935281a 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/AttendanceArrangementBo.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/AttendanceArrangementBo.java @@ -9,6 +9,7 @@ import io.github.linpeilie.annotations.AutoMapper; import lombok.Data; import lombok.EqualsAndHashCode; import jakarta.validation.constraints.*; +import org.dromara.property.domain.AttendanceScheduleCycle; import org.dromara.property.domain.AttendanceUserGroup; import org.springframework.format.annotation.DateTimeFormat; @@ -52,7 +53,7 @@ public class AttendanceArrangementBo extends BaseEntity { /** * 日期类型:1-单个日期,2-长期有效,3-期间有效 */ - private Long dateType; + private Integer dateType; /** * 开始日期 @@ -69,8 +70,8 @@ public class AttendanceArrangementBo extends BaseEntity { /** * 前端传日历的开始时间和结束时间 */ - private LocalDate calendarStartDate; - private LocalDate calendarEndTimeDate; + private Date calendarStartDate; + private Date calendarEndTimeDate; /** * 前端传某天的当前日期 @@ -83,7 +84,15 @@ public class AttendanceArrangementBo extends BaseEntity { */ private Long status; + /** + * + * 排班用户组 + */ private List userGroupList; + /** + * 排班日期列表 + */ + private List scheduleCycleList; } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/constant/StatusConstant.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/constant/StatusConstant.java index efc6f43b..188b613e 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/constant/StatusConstant.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/constant/StatusConstant.java @@ -28,5 +28,11 @@ public class StatusConstant { public static final Integer NORMAL = 1; + //日期类型:1-单个日期,2-长期有效,3-期间有效 + public static final Integer SINGLE = 1; + public static final Integer LONGTIME = 2; + public static final Integer SHORTTIME = 3; + + } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/AttendanceArrangementVo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/AttendanceArrangementVo.java index c6ca7b0a..9f9fc293 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/AttendanceArrangementVo.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/AttendanceArrangementVo.java @@ -8,7 +8,7 @@ import org.dromara.property.domain.*; import java.io.Serial; import java.io.Serializable; -import java.time.LocalDate; +import java.util.Date; import java.util.List; @@ -60,13 +60,13 @@ public class AttendanceArrangementVo implements Serializable { * 开始日期 */ @ExcelProperty(value = "开始日期") - private LocalDate startDate; + private Date startDate; /** * 结束日期(仅date_type=3时有效) */ @ExcelProperty(value = "结束日期(仅date_type=3时有效)") - private LocalDate endDate; + private Date endDate; /** * 状态:0-未生效,1-已生效 diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceArrangementServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceArrangementServiceImpl.java index 5181deca..42261de6 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceArrangementServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceArrangementServiceImpl.java @@ -19,6 +19,8 @@ import org.dromara.property.service.IAttendanceArrangementService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDate; +import java.time.ZoneId; import java.util.*; import java.util.stream.Collectors; @@ -75,63 +77,69 @@ public class AttendanceArrangementServiceImpl implements IAttendanceArrangementS LambdaQueryWrapper lqw = buildQueryWrapper(bo); Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); - //1.如:在2号到10号有固定班制和排班制,根据当前日期查询出所有的考勤组id - //查询指定日期在哪些排班中 - List arrangementList = baseMapper.selectList(Wrappers.lambdaQuery().ge(AttendanceArrangement::getStartDate, bo.getCurrentDate()).le(AttendanceArrangement::getEndDate, bo.getCurrentDate())); - //根据排班查询出考勤组id - List groupIds = arrangementList.stream().map(AttendanceArrangement::getGroupId).distinct().toList(); - // 2.循环将所有的考勤组id设置到考勤组中 - //循环groupIds,循环和AttendanceGroup中的id做对比,如果有相同的,则取出attendanceGroup中的所有数据 - groupIds.forEach( - groupId -> { - //从数据库查询出当前考勤组的所有数据 - AttendanceGroup group = attendanceGroupMapper.selectOne(Wrappers.lambdaQuery().eq(AttendanceGroup::getId, groupId)); + Page attendanceArrangementVoPage = result.setRecords(result.getRecords().stream().peek(vo -> { - // 3.查询出当前考勤组的所有数据,从考勤组判断当前id是固定班制还是排班制 - if (group.getAttendanceType().equals(StatusConstant.FIXEDSCHEDULE)) { - // 3.1固定班制:将当前的日期转为周几,然后与数据库中的班次周数作对比,取出当前日期的班次信息 - //将传来的日期参数转为周几 - int week = DateUtil.dayOfWeek(bo.getCurrentDate()); - //取出当前日期的周数,与数据库中的班次周数作对比,取出当前日期的班次信息 - AttendanceWeekSet weekSet = weekSetMapper.selectOne(Wrappers.lambdaQuery().eq(AttendanceWeekSet::getGroupId, groupId).eq(AttendanceWeekSet::getDayOfWeek, week)); - //将weekSet存到结果中 - AttendanceArrangementVo arrangementVo = new AttendanceArrangementVo(); - arrangementVo.setWeekSet(weekSet); - //根据weekSet取出id,根据id查询出attendanceWeekSetShift表中的shiftId - Long shiftId = weekSet.getId(); - //根据shiftId查询attendanceShift表中对应的id的数据 - AttendanceShift shift = attendanceShiftMapper.selectById(shiftId); - //将shift存到结果中 - arrangementVo.setShift(shift); + //1.如:在2号到10号有固定班制和排班制,根据当前日期查询出所有的考勤组id + //查询指定日期在哪些排班中 + List arrangementList = baseMapper.selectList(Wrappers.lambdaQuery().ge(AttendanceArrangement::getStartDate, bo.getCurrentDate()).le(AttendanceArrangement::getEndDate, bo.getCurrentDate())); + //根据排班查询出考勤组id + List groupIds = arrangementList.stream().map(AttendanceArrangement::getGroupId).distinct().toList(); - } else if (group.getAttendanceType().equals(StatusConstant.SHIFTSCHEDULE)) { - // 3.2排班制:判断第一天是从几号开始,循环判断,判断当前是循环中的第几天,取出当前天数的班次信息。 - //取出排班中的开始时间和结束时间 - Date startDate = bo.getStartDate(); - Date endDate = bo.getEndDate(); - Date currentDate = bo.getCurrentDate(); - //取出attendanceScheduleCycle表中的天数 - Integer cycleDays = scheduleCycleMapper.selectOne(Wrappers.lambdaQuery().eq(AttendanceScheduleCycle::getGroupId, groupId)).getDayNumber(); - //在startDate和endDate之间循环,判端当前日期是cycleDays中的第几天 - int cycleDay = 0; - while (startDate.before(currentDate) || endDate.after(currentDate)) { - cycleDay++; - startDate = DateUtil.offsetDay(startDate, 1); - //判断当前日期是clcleDays中的第几天 - if (cycleDay > cycleDays) { - cycleDay = 1; + // 2.循环将所有的考勤组id设置到考勤组中 + //循环groupIds,循环和AttendanceGroup中的id做对比,如果有相同的,则取出attendanceGroup中的所有数据 + groupIds.forEach( + groupId -> { + //从数据库查询出当前考勤组的所有数据 + AttendanceGroup group = attendanceGroupMapper.selectOne(Wrappers.lambdaQuery().eq(AttendanceGroup::getId, groupId)); + + // 3.查询出当前考勤组的所有数据,从考勤组判断当前id是固定班制还是排班制 + if (group.getAttendanceType().equals(StatusConstant.FIXEDSCHEDULE)) { + // 3.1固定班制:将当前的日期转为周几,然后与数据库中的班次周数作对比,取出当前日期的班次信息 + //将传来的日期参数转为周几 + int week = DateUtil.dayOfWeek(bo.getCurrentDate()); + //取出当前日期的周数,与数据库中的班次周数作对比,取出当前日期的班次信息 + AttendanceWeekSet weekSet = weekSetMapper.selectOne(Wrappers.lambdaQuery().eq(AttendanceWeekSet::getGroupId, groupId).eq(AttendanceWeekSet::getDayOfWeek, week)); + //将weekSet存到结果中 + AttendanceArrangementVo arrangementVo = new AttendanceArrangementVo(); + arrangementVo.setWeekSet(weekSet); + //根据weekSet取出id,根据id查询出attendanceWeekSetShift表中的shiftId + Long shiftId = weekSet.getId(); + //根据shiftId查询attendanceShift表中对应的id的数据 + AttendanceShift shift = attendanceShiftMapper.selectById(shiftId); + //将shift存到结果中 + arrangementVo.setShift(shift); + + } else if (group.getAttendanceType().equals(StatusConstant.SHIFTSCHEDULE)) { + // 3.2排班制:判断第一天是从几号开始,循环判断,判断当前是循环中的第几天,取出当前天数的班次信息。 + //取出排班中的开始时间和结束时间 + Date startDate = bo.getStartDate(); + Date endDate = bo.getEndDate(); + Date currentDate = bo.getCurrentDate(); + //取出attendanceScheduleCycle表中的天数 + Integer cycleDays = scheduleCycleMapper.selectOne(Wrappers.lambdaQuery().eq(AttendanceScheduleCycle::getGroupId, groupId)).getDayNumber(); + //在startDate和endDate之间循环,判端当前日期是cycleDays中的第几天 + int cycleDay = 0; + while (startDate.before(currentDate) || endDate.after(currentDate)) { + cycleDay++; + startDate = DateUtil.offsetDay(startDate, 1); + //判断当前日期是clcleDays中的第几天 + if (cycleDay > cycleDays) { + cycleDay = 1; + } } - } - //根据cycleDay查询出当前日期的班次信息 - AttendanceScheduleCycle cycle = scheduleCycleMapper.selectOne(Wrappers.lambdaQuery().eq(AttendanceScheduleCycle::getGroupId, groupId).eq(AttendanceScheduleCycle::getDayNumber, cycleDay)); - //将cycle存到结果中 - AttendanceArrangementVo arrangementVo = new AttendanceArrangementVo(); - arrangementVo.setCycle(cycle); + //根据cycleDay查询出当前日期的班次信息 + AttendanceScheduleCycle cycle = scheduleCycleMapper.selectOne(Wrappers.lambdaQuery().eq(AttendanceScheduleCycle::getGroupId, groupId).eq(AttendanceScheduleCycle::getDayNumber, cycleDay)); + //将cycle存到结果中 + AttendanceArrangementVo arrangementVo = new AttendanceArrangementVo(); + arrangementVo.setCycle(cycle); + } } - } - ); + ); + }).collect(Collectors.toList())); + + // //1.根据当前日期查询出排班信息 @@ -154,7 +162,7 @@ public class AttendanceArrangementServiceImpl implements IAttendanceArrangementS // } - return TableDataInfo.build(result); + return TableDataInfo.build(attendanceArrangementVoPage); } /** @@ -244,6 +252,23 @@ public class AttendanceArrangementServiceImpl implements IAttendanceArrangementS if (flag) { bo.setId(add.getId()); } + + //判断排班日期是单个日期还是从此日期开始循环有效还是从此日期开始有效 + //1.单个日期 + if (bo.getDateType().equals(StatusConstant.SINGLE)) { + add.setEndDate(null); + } + //2.从此日期开始长期有效 + if (bo.getDateType().equals(StatusConstant.LONGTIME)) { + //设置长期时间为2099年12月31日 + LocalDate longTimeEndDate = LocalDate.of(2099, 12, 31); + add.setEndDate(Date.from(longTimeEndDate.atStartOfDay(ZoneId.systemDefault()).toInstant())); + } + if (bo.getDateType().equals(StatusConstant.SHORTTIME)){ + add.setEndDate(bo.getEndDate()); + } + + //取出当前新增的排班的id Long ArrangementId = add.getId(); //用获取到的排班id向attendanceUserGroup表中插入数据 From da0ba9aa0a0b0d805b6d1ca17f75f0b359a516e7 Mon Sep 17 00:00:00 2001 From: dy <2389062315@qq.com> Date: Tue, 29 Jul 2025 11:08:59 +0800 Subject: [PATCH 4/9] =?UTF-8?q?=E6=8A=BD=E5=8F=96=E5=85=AC=E5=85=B1?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AttendanceArrangementServiceImpl.java | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceArrangementServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceArrangementServiceImpl.java index 42261de6..5a87edcd 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceArrangementServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceArrangementServiceImpl.java @@ -253,20 +253,7 @@ public class AttendanceArrangementServiceImpl implements IAttendanceArrangementS bo.setId(add.getId()); } - //判断排班日期是单个日期还是从此日期开始循环有效还是从此日期开始有效 - //1.单个日期 - if (bo.getDateType().equals(StatusConstant.SINGLE)) { - add.setEndDate(null); - } - //2.从此日期开始长期有效 - if (bo.getDateType().equals(StatusConstant.LONGTIME)) { - //设置长期时间为2099年12月31日 - LocalDate longTimeEndDate = LocalDate.of(2099, 12, 31); - add.setEndDate(Date.from(longTimeEndDate.atStartOfDay(ZoneId.systemDefault()).toInstant())); - } - if (bo.getDateType().equals(StatusConstant.SHORTTIME)){ - add.setEndDate(bo.getEndDate()); - } + judgeDate(bo, add); //取出当前新增的排班的id @@ -282,6 +269,23 @@ public class AttendanceArrangementServiceImpl implements IAttendanceArrangementS return flag; } + private static void judgeDate(AttendanceArrangementBo bo, AttendanceArrangement add) { + //判断排班日期是单个日期还是从此日期开始循环有效还是从此日期开始有效 + //1.单个日期 + if (bo.getDateType().equals(StatusConstant.SINGLE)) { + add.setEndDate(null); + } + //2.从此日期开始长期有效 + if (bo.getDateType().equals(StatusConstant.LONGTIME)) { + //设置长期时间为2099年12月31日 + LocalDate longTimeEndDate = LocalDate.of(2099, 12, 31); + add.setEndDate(Date.from(longTimeEndDate.atStartOfDay(ZoneId.systemDefault()).toInstant())); + } + if (bo.getDateType().equals(StatusConstant.SHORTTIME)){ + add.setEndDate(bo.getEndDate()); + } + } + /** * 修改排班 * @@ -293,6 +297,8 @@ public class AttendanceArrangementServiceImpl implements IAttendanceArrangementS AttendanceArrangement update = MapstructUtils.convert(bo, AttendanceArrangement.class); validEntityBeforeSave(update); + judgeDate(bo, update); + //取出当前排班的id Long ArrangementId = update.getId(); //用获取到的排班id向attendanceUserGroup表中更新数据 From b303ab6faaae0ae183a3db883688659f4026e99c Mon Sep 17 00:00:00 2001 From: dy <2389062315@qq.com> Date: Tue, 29 Jul 2025 15:47:40 +0800 Subject: [PATCH 5/9] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=9B=BA=E5=AE=9A?= =?UTF-8?q?=E7=8F=AD=E5=88=B6=E4=B8=BB=E9=94=AE=E9=87=8D=E5=A4=8D=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/dromara/property/domain/bo/AttendanceGroupBo.java | 1 + .../service/impl/AttendanceArrangementServiceImpl.java | 6 +++++- .../property/service/impl/AttendanceGroupServiceImpl.java | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/AttendanceGroupBo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/AttendanceGroupBo.java index 222f8a81..01e3fd5e 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/AttendanceGroupBo.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/AttendanceGroupBo.java @@ -50,6 +50,7 @@ public class AttendanceGroupBo extends BaseEntity { List numList; + List weekSetList; diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceArrangementServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceArrangementServiceImpl.java index 5a87edcd..6c5c3c5b 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceArrangementServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceArrangementServiceImpl.java @@ -174,7 +174,11 @@ public class AttendanceArrangementServiceImpl implements IAttendanceArrangementS @Override public List queryList(AttendanceArrangementBo bo) { - //1.根据开始时间和结束时间查询所有的排班信息 + //查看日历开始时间、结束时间和开始时间、结束时间的交集 + + + + //1.根据日历的开始时间和日历的结束时间查询所有的排班信息 List arrangementList = baseMapper.selectList(Wrappers.lambdaQuery().ge(AttendanceArrangement::getStartDate, bo.getCalendarStartDate()).le(AttendanceArrangement::getEndDate, bo.getCalendarEndTimeDate())); //2.查询人员组的信息 //根据开始时间查询排班的id diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceGroupServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceGroupServiceImpl.java index 838dbadb..878466d7 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceGroupServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceGroupServiceImpl.java @@ -203,11 +203,11 @@ public class AttendanceGroupServiceImpl implements IAttendanceGroupService { //3.排班制 if (Objects.equals(add.getAttendanceType(), StatusConstant.SHIFTSCHEDULE)) { - //2.2排班制,向天数表中插入数据 - AttendanceScheduleCycle attendanceScheduleCycle = new AttendanceScheduleCycle(); //循环向周期表中插入数据 bo.getNumList().forEach( num -> { + //2.2排班制,向天数表中插入数据 + AttendanceScheduleCycle attendanceScheduleCycle = new AttendanceScheduleCycle(); attendanceScheduleCycle.setGroupId(add.getId()); attendanceScheduleCycle.setDayNumber(num.getDayNumber()); attendanceScheduleCycleMapper.insert(attendanceScheduleCycle); From 28143d17e7a8234a77a7fac17139d46753c66aa4 Mon Sep 17 00:00:00 2001 From: dy <2389062315@qq.com> Date: Tue, 29 Jul 2025 16:59:17 +0800 Subject: [PATCH 6/9] =?UTF-8?q?=E8=AF=A6=E6=83=85bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/AttendanceScheduleCycle.java | 2 +- .../property/domain/bo/AttendanceGroupBo.java | 1 - .../property/domain/vo/AttendanceGroupVo.java | 4 ++ .../AttendanceArrangementServiceImpl.java | 7 +++- .../impl/AttendanceGroupServiceImpl.java | 38 ++++++++++++++----- 5 files changed, 40 insertions(+), 12 deletions(-) diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/AttendanceScheduleCycle.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/AttendanceScheduleCycle.java index d935277c..8787667b 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/AttendanceScheduleCycle.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/AttendanceScheduleCycle.java @@ -42,7 +42,7 @@ public class AttendanceScheduleCycle extends TenantEntity { */ private Long isRest; - private Long scheduleId; + private Long shiftId; } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/AttendanceGroupBo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/AttendanceGroupBo.java index 01e3fd5e..222f8a81 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/AttendanceGroupBo.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/AttendanceGroupBo.java @@ -50,7 +50,6 @@ public class AttendanceGroupBo extends BaseEntity { List numList; - List weekSetList; diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/AttendanceGroupVo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/AttendanceGroupVo.java index 44c1c8f0..b8ae3945 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/AttendanceGroupVo.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/AttendanceGroupVo.java @@ -61,5 +61,9 @@ public class AttendanceGroupVo implements Serializable { List clockDateList; + List scheduleCycleList; + + + } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceArrangementServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceArrangementServiceImpl.java index 6c5c3c5b..2271d73c 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceArrangementServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceArrangementServiceImpl.java @@ -174,7 +174,12 @@ public class AttendanceArrangementServiceImpl implements IAttendanceArrangementS @Override public List queryList(AttendanceArrangementBo bo) { - //查看日历开始时间、结束时间和开始时间、结束时间的交集 + Date startDate = bo.getStartDate(); + Date endDate = bo.getEndDate(); + Date calendarStartDate = bo.getCalendarStartDate(); + Date calendarEndTimeDate = bo.getCalendarEndTimeDate(); + + diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceGroupServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceGroupServiceImpl.java index 878466d7..6e9a8394 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceGroupServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceGroupServiceImpl.java @@ -78,18 +78,38 @@ public class AttendanceGroupServiceImpl implements IAttendanceGroupService { vo.setWeekList(weekSets); } else if (Objects.equals(attendanceType, SHIFTSCHEDULE)) { //2.排班制 - //2.1根据id参数查询考勤周期表 - List weekSets = weekSetMapper.selectList(Wrappers.lambdaQuery().eq(AttendanceWeekSet::getGroupId, id)); + //2.1根据id参数查询考勤天数表 + List scheduleCycles = attendanceScheduleCycleMapper.selectList(Wrappers.lambdaQuery().eq(AttendanceScheduleCycle::getGroupId, id)); //2.2根据id参数取出所有考勤天数id - List weekSetIds = weekSets.stream().map(AttendanceWeekSet::getId).toList(); - //2.3根据天数id查询出中间表 - List scheduleCycles = attendanceScheduleCycleMapper.selectList(Wrappers.lambdaQuery().in(AttendanceScheduleCycle::getGroupId, weekSetIds)); - //2.4根据中间表的班次id查询出班次表id List scheduleCycleIds = scheduleCycles.stream().map(AttendanceScheduleCycle::getId).toList(); - //2.5根据班次id查询出班次表 - List shifts = attendanceShiftMapper.selectList(Wrappers.lambdaQuery().in(AttendanceShift::getId, scheduleCycleIds)); + //2.3根据天数id查询出中间表 + List weeksetShifts = attendanceWeeksetShiftMapper.selectList(Wrappers.lambdaQuery().in(AttendanceWeeksetShift::getWeekSetId, scheduleCycleIds)); + //2.4根据中间表的班次id查询出班次表id + List weeksetShiftIds = weeksetShifts.stream().map(AttendanceWeeksetShift::getId).toList(); + //根据id查询出shiftId + List shiftIds = weeksetShifts.stream().map(AttendanceWeeksetShift::getShiftId).toList(); + //2.5根据shiftId查询出班次表 + List shifts = attendanceShiftMapper.selectList(Wrappers.lambdaQuery().in(AttendanceShift::getId, shiftIds)); + + +// //2.5根据班次id查询出班次表 +// List shifts = attendanceShiftMapper.selectList(Wrappers.lambdaQuery().in(AttendanceShift::getId, weeksetShiftIds)); //2.6将查询后的数据封装到attendanceGroupVo中 vo.setAttendanceList(shifts); + vo.setScheduleCycleList(scheduleCycles); + + +// List weekSets = weekSetMapper.selectList(Wrappers.lambdaQuery().eq(AttendanceWeekSet::getGroupId, id)); +// //2.2根据id参数取出所有考勤天数id +// List weekSetIds = weekSets.stream().map(AttendanceWeekSet::getId).toList(); +// //2.3根据天数id查询出中间表 +// List scheduleCycles = attendanceScheduleCycleMapper.selectList(Wrappers.lambdaQuery().in(AttendanceScheduleCycle::getGroupId, weekSetIds)); +// //2.4根据中间表的班次id查询出班次表id +// List scheduleCycleIds = scheduleCycles.stream().map(AttendanceScheduleCycle::getId).toList(); +// //2.5根据班次id查询出班次表 +// List shifts = attendanceShiftMapper.selectList(Wrappers.lambdaQuery().in(AttendanceShift::getId, scheduleCycleIds)); +// //2.6将查询后的数据封装到attendanceGroupVo中 +// vo.setAttendanceList(shifts); } //根据id查询attendance_clock_date表 @@ -216,7 +236,7 @@ public class AttendanceGroupServiceImpl implements IAttendanceGroupService { //向中间表插入周期的id AttendanceWeeksetShift attendanceWeeksetShift = new AttendanceWeeksetShift(); attendanceWeeksetShift.setWeekSetId(scheduleId); - attendanceWeeksetShift.setShiftId(num.getScheduleId()); + attendanceWeeksetShift.setShiftId(num.getShiftId()); attendanceWeeksetShiftMapper.insert(attendanceWeeksetShift); } ); From d42e2c627fae618857daca06c308a40e1586b24b Mon Sep 17 00:00:00 2001 From: dy <2389062315@qq.com> Date: Tue, 29 Jul 2025 17:15:45 +0800 Subject: [PATCH 7/9] =?UTF-8?q?=E7=8F=AD=E6=AC=A1id=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/AttendanceGroupServiceImpl.java | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceGroupServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceGroupServiceImpl.java index 6e9a8394..158d2dba 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceGroupServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceGroupServiceImpl.java @@ -90,26 +90,10 @@ public class AttendanceGroupServiceImpl implements IAttendanceGroupService { List shiftIds = weeksetShifts.stream().map(AttendanceWeeksetShift::getShiftId).toList(); //2.5根据shiftId查询出班次表 List shifts = attendanceShiftMapper.selectList(Wrappers.lambdaQuery().in(AttendanceShift::getId, shiftIds)); - - -// //2.5根据班次id查询出班次表 -// List shifts = attendanceShiftMapper.selectList(Wrappers.lambdaQuery().in(AttendanceShift::getId, weeksetShiftIds)); //2.6将查询后的数据封装到attendanceGroupVo中 vo.setAttendanceList(shifts); vo.setScheduleCycleList(scheduleCycles); - -// List weekSets = weekSetMapper.selectList(Wrappers.lambdaQuery().eq(AttendanceWeekSet::getGroupId, id)); -// //2.2根据id参数取出所有考勤天数id -// List weekSetIds = weekSets.stream().map(AttendanceWeekSet::getId).toList(); -// //2.3根据天数id查询出中间表 -// List scheduleCycles = attendanceScheduleCycleMapper.selectList(Wrappers.lambdaQuery().in(AttendanceScheduleCycle::getGroupId, weekSetIds)); -// //2.4根据中间表的班次id查询出班次表id -// List scheduleCycleIds = scheduleCycles.stream().map(AttendanceScheduleCycle::getId).toList(); -// //2.5根据班次id查询出班次表 -// List shifts = attendanceShiftMapper.selectList(Wrappers.lambdaQuery().in(AttendanceShift::getId, scheduleCycleIds)); -// //2.6将查询后的数据封装到attendanceGroupVo中 -// vo.setAttendanceList(shifts); } //根据id查询attendance_clock_date表 @@ -230,6 +214,7 @@ public class AttendanceGroupServiceImpl implements IAttendanceGroupService { AttendanceScheduleCycle attendanceScheduleCycle = new AttendanceScheduleCycle(); attendanceScheduleCycle.setGroupId(add.getId()); attendanceScheduleCycle.setDayNumber(num.getDayNumber()); + attendanceScheduleCycle.setShiftId(num.getShiftId()); attendanceScheduleCycleMapper.insert(attendanceScheduleCycle); //获取周期表的id Long scheduleId = attendanceScheduleCycle.getId(); From 21985e48e75705240f3842e8d53568f49a77b04f Mon Sep 17 00:00:00 2001 From: zcxlsm Date: Tue, 29 Jul 2025 18:37:03 +0800 Subject: [PATCH 8/9] =?UTF-8?q?fix(sis):=20=E4=BC=98=E5=8C=96=E4=BA=BA?= =?UTF-8?q?=E8=84=B8=E7=85=A7=E7=89=87=E5=90=8C=E6=AD=A5=E5=92=8C=E6=8E=88?= =?UTF-8?q?=E6=9D=83=E8=AE=B0=E5=BD=95=E6=9B=B4=E6=96=B0=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/domain/vo/RemoteResidentPersonVo.java | 2 + .../org/dromara/sis/api/RemoteSisAuth.java | 2 + .../sis/api/domain/RemotePersonAuth.java | 2 + .../impl/ResidentPersonServiceImpl.java | 54 ++++++++++++- .../controller/SisAuthRecordController.java | 14 ++-- .../dromara/sis/domain/SisPersonLibImg.java | 5 ++ .../sis/domain/bo/SisPersonLibImgBo.java | 5 ++ .../sis/domain/vo/SisPersonLibImgVo.java | 6 ++ .../dromara/sis/dubbo/RemoteSisAuthImpl.java | 5 ++ .../sis/service/ISisAuthRecordService.java | 4 +- .../sis/service/ISisPersonLibImgService.java | 18 ++++- .../impl/SisAuthRecordServiceImpl.java | 77 +++++++++++++++++-- .../impl/SisPersonLibImgServiceImpl.java | 39 +++++++++- .../org/dromara/sis/task/AuthSyncTask.java | 74 ++++++++++++++++-- .../mapper/sis/SisAuthRecordMapper.xml | 2 +- 15 files changed, 279 insertions(+), 30 deletions(-) diff --git a/ruoyi-api/property-api/src/main/java/org/dromara/property/api/domain/vo/RemoteResidentPersonVo.java b/ruoyi-api/property-api/src/main/java/org/dromara/property/api/domain/vo/RemoteResidentPersonVo.java index 01409e4e..fe4cb830 100644 --- a/ruoyi-api/property-api/src/main/java/org/dromara/property/api/domain/vo/RemoteResidentPersonVo.java +++ b/ruoyi-api/property-api/src/main/java/org/dromara/property/api/domain/vo/RemoteResidentPersonVo.java @@ -25,6 +25,8 @@ public class RemoteResidentPersonVo implements Serializable { private Long gender; + private String phone; + private String idCard; private Long authGroupId; 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 index 9e7caf2f..c8514320 100644 --- 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 @@ -10,4 +10,6 @@ import org.dromara.sis.api.domain.RemotePersonAuth; public interface RemoteSisAuth { Boolean personAuth(RemotePersonAuth personAuth); + + Boolean updatePersonAuth(RemotePersonAuth personAuth); } diff --git a/ruoyi-api/sis-api/src/main/java/org/dromara/sis/api/domain/RemotePersonAuth.java b/ruoyi-api/sis-api/src/main/java/org/dromara/sis/api/domain/RemotePersonAuth.java index f6c80e75..c08c1dfe 100644 --- a/ruoyi-api/sis-api/src/main/java/org/dromara/sis/api/domain/RemotePersonAuth.java +++ b/ruoyi-api/sis-api/src/main/java/org/dromara/sis/api/domain/RemotePersonAuth.java @@ -27,6 +27,8 @@ public class RemotePersonAuth implements Serializable { private String email; + private Long e8Id; + private Integer cardType = 1; private String idCardNumber; 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 762ad13b..2c74f403 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ResidentPersonServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ResidentPersonServiceImpl.java @@ -1,6 +1,7 @@ package org.dromara.property.service.impl; import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.dubbo.config.annotation.DubboReference; import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.StringUtils; @@ -159,15 +160,60 @@ public class ResidentPersonServiceImpl implements IResidentPersonService { @Override public Boolean updateByBo(ResidentPersonBo bo) { ResidentPerson update = MapstructUtils.convert(bo, ResidentPerson.class); - validEntityBeforeUpdate(update); - return baseMapper.updateById(update) > 0; + assert update != null; + + boolean flag; + // 人脸照片存在时,才同步修改授权 + if (update.getAuthGroupId() != null && update.getAuthEndDate() != null && update.getImg() != null) { + ResidentPersonVo vo = queryById(update.getId()); + Long e8Id = vo.getEEightId(); + flag = baseMapper.updateById(update) > 0; + + // 显式移除e8id + LambdaUpdateWrapper lqw = new LambdaUpdateWrapper<>(); + lqw.eq(ResidentPerson::getId, update.getId()) + .set(ResidentPerson::getEEightId, ""); + baseMapper.update(lqw); + + + if (flag) { + log.info("开始修改授权记录, {}", bo.getUserName()); + RemotePersonAuth personAuth = new RemotePersonAuth(); + personAuth.setId(update.getId()); + personAuth.setName(update.getUserName()); + personAuth.setSex(update.getGender().intValue()); + personAuth.setPhone(update.getPhone()); + personAuth.setEmail(update.getEmail()); + personAuth.setIdCardNumber(update.getIdCard()); + personAuth.setOssId(update.getImg()); + personAuth.setCarNumber(update.getCarNumber()); + personAuth.setE8Id(e8Id); + + personAuth.setAuthGroupId(update.getAuthGroupId()); + personAuth.setAuthBegDate(update.getAuthBegDate()); + personAuth.setAuthEndDate(update.getAuthEndDate()); + + Boolean auth = remoteSisAuth.updatePersonAuth(personAuth); + Assert.isTrue(auth, "修改授权记录失败!"); + } + + } else { + flag = baseMapper.updateById(update) > 0; + } + + Assert.isTrue(flag, "修改入驻员工失败!"); + return flag; } /** * 保存前的数据校验 */ private void validEntityBeforeUpdate(ResidentPerson entity) { - //TODO 做一些数据校验,如唯一约束 + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(ResidentPerson::getIdCard, entity.getIdCard()) + .eq(ResidentPerson::getUnitId, entity.getUnitId()); + boolean exists = baseMapper.exists(lqw); + Assert.isTrue(!exists, "当前单位,{}已存在!", entity.getUserName()); } /** @@ -226,7 +272,7 @@ public class ResidentPersonServiceImpl implements IResidentPersonService { * @return List */ @Override - public List queryUnAuthPerson(){ + public List queryUnAuthPerson() { LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); lqw.isNotNull(ResidentPerson::getImg) .ne(ResidentPerson::getImg, "") diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/controller/SisAuthRecordController.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/controller/SisAuthRecordController.java index 9b8d9a6a..65869781 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/controller/SisAuthRecordController.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/controller/SisAuthRecordController.java @@ -83,13 +83,13 @@ public class SisAuthRecordController extends BaseController { /** * 修改授权记录 */ - @SaCheckPermission("sis:authRecord:edit") - @Log(title = "授权记录", businessType = BusinessType.UPDATE) - @RepeatSubmit() - @PutMapping() - public R edit(@Validated(EditGroup.class) @RequestBody SisAuthRecordBo bo) { - return toAjax(sisAuthRecordService.updateByBo(bo)); - } +// @SaCheckPermission("sis:authRecord:edit") +// @Log(title = "授权记录", businessType = BusinessType.UPDATE) +// @RepeatSubmit() +// @PutMapping() +// public R edit(@Validated(EditGroup.class) @RequestBody SisAuthRecordBo bo) { +// return toAjax(sisAuthRecordService.updateByBo(bo)); +// } /** * 删除授权记录 diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/SisPersonLibImg.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/SisPersonLibImg.java index afe110e9..1d325904 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/SisPersonLibImg.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/SisPersonLibImg.java @@ -78,4 +78,9 @@ public class SisPersonLibImg extends TenantEntity { */ private Long residentPersonId; + /** + * 图片MD5 + */ + private String imgMd5Value; + } diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/bo/SisPersonLibImgBo.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/bo/SisPersonLibImgBo.java index 15358a83..abb1c577 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/bo/SisPersonLibImgBo.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/bo/SisPersonLibImgBo.java @@ -86,4 +86,9 @@ public class SisPersonLibImgBo extends BaseEntity { */ private Long residentPersonId; + /** + * 图片MD5 + */ + private String imgMd5Value; + } diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/vo/SisPersonLibImgVo.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/vo/SisPersonLibImgVo.java index ecbd52b3..d9998833 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/vo/SisPersonLibImgVo.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/vo/SisPersonLibImgVo.java @@ -96,4 +96,10 @@ public class SisPersonLibImgVo implements Serializable { */ @ExcelProperty(value = "入驻员工id") private Long residentPersonId; + + /** + * 图片MD5 + */ + @ExcelProperty(value = "图片MD5") + private String imgMd5Value; } 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 index 79e0764d..c5573b02 100644 --- 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 @@ -23,4 +23,9 @@ public class RemoteSisAuthImpl implements RemoteSisAuth { public Boolean personAuth(RemotePersonAuth personAuth) { return sisAuthRecordService.insertByPerson(personAuth); } + + @Override + public Boolean updatePersonAuth(RemotePersonAuth personAuth) { + return sisAuthRecordService.updateByBo(personAuth); + } } diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/ISisAuthRecordService.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/ISisAuthRecordService.java index a9848854..a3120950 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/ISisAuthRecordService.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/ISisAuthRecordService.java @@ -52,12 +52,12 @@ public interface ISisAuthRecordService { Boolean insertByPerson(RemotePersonAuth bo); /** - * 修改授权记录 + * 修改授权记录(单个) * * @param bo 授权记录 * @return 是否修改成功 */ - Boolean updateByBo(SisAuthRecordBo bo); + Boolean updateByBo(RemotePersonAuth bo); /** * 校验并批量删除授权记录信息 diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/ISisPersonLibImgService.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/ISisPersonLibImgService.java index 621a00ea..5fed2f8f 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/ISisPersonLibImgService.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/ISisPersonLibImgService.java @@ -79,7 +79,23 @@ public interface ISisPersonLibImgService { * * @param personId 入驻员工id * @param huaweiBoxId 华为盒子图像id + * @param imgMd5 图片md5值 * @return Boolean */ - Boolean updateByPersonId(Long personId, Long huaweiBoxId); + Boolean updateByPersonId(Long personId, Long huaweiBoxId, String imgMd5); + + + /** + * 根据图片MD5,查询图片 + * + * @param imgMd5 图片MD5 + */ + SisPersonLibImgVo queryByImgMd5(String imgMd5); + + /** + * 根据入驻员工id,查询图片 + * + * @param personId 入驻员工id + */ + SisPersonLibImgVo queryByPersonId(Long personId); } diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisAuthRecordServiceImpl.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisAuthRecordServiceImpl.java index 01f8ce2b..129d38db 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisAuthRecordServiceImpl.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisAuthRecordServiceImpl.java @@ -13,12 +13,16 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.dromara.property.api.RemoteFloorService; import org.dromara.property.api.domain.vo.RemoteFloorVo; +import org.dromara.resource.api.RemoteFileService; import org.dromara.sis.api.domain.RemotePersonAuth; import org.dromara.sis.domain.bo.SisAccessControlBo; import org.dromara.sis.domain.bo.SisElevatorInfoBo; import org.dromara.sis.domain.bo.SisPersonLibImgBo; import org.dromara.sis.domain.vo.SisAccessControlVo; import org.dromara.sis.domain.vo.SisElevatorInfoVo; +import org.dromara.sis.domain.vo.SisPersonLibImgVo; +import org.dromara.sis.sdk.e8.E8PlatformApi; +import org.dromara.sis.sdk.huawei.HuaWeiBoxApi; import org.dromara.sis.service.*; import org.springframework.stereotype.Service; import org.dromara.sis.domain.bo.SisAuthRecordBo; @@ -27,6 +31,7 @@ import org.dromara.sis.domain.SisAuthRecord; import org.dromara.sis.mapper.SisAuthRecordMapper; import org.springframework.transaction.annotation.Transactional; +import java.security.MessageDigest; import java.util.*; /** @@ -40,6 +45,8 @@ import java.util.*; @Service public class SisAuthRecordServiceImpl implements ISisAuthRecordService { + private final E8PlatformApi e8PlatformApi; + private final SisAuthRecordMapper baseMapper; private final ISisElevatorInfoService elevatorInfoService; private final ISisPersonLibImgService sisPersonLibImgService; @@ -48,6 +55,9 @@ public class SisAuthRecordServiceImpl implements ISisAuthRecordService { @DubboReference private RemoteFloorService remoteFloorService; + @DubboReference + private RemoteFileService remoteFileService; + /** * 查询授权记录 * @@ -112,30 +122,69 @@ public class SisAuthRecordServiceImpl implements ISisAuthRecordService { add.setGroupId(bo.getAuthGroupId()); add.setBegDate(bo.getAuthBegDate()); add.setEndDate(bo.getAuthEndDate()); + add.setTenantId("000000"); boolean flag = baseMapper.insert(add) > 0; Assert.isTrue(flag, "新增授权记录失败"); - if (flag) { + try { + // 记录图片md5值 + byte[] imgByte = remoteFileService.downloadToByteArray(Long.parseLong(bo.getOssId())); + String md5 = calculateMD5(imgByte); // 写入安防人像信息 - this.syncPersonImg(bo); + this.syncPersonImg(bo, md5); + } catch (Exception e) { + log.info("下载图片失败"); } return flag; } - private void syncPersonImg(RemotePersonAuth bo) { + private void syncPersonImg(RemotePersonAuth bo, String md5) { log.info("开始写入安防人像信息"); SisPersonLibImgBo personLibImg = new SisPersonLibImgBo(); personLibImg.setImgOssId(Long.parseLong(bo.getOssId())); + personLibImg.setTel(bo.getPhone()); personLibImg.setImgName(bo.getName()); personLibImg.setSex(bo.getSex()); personLibImg.setCertificateType(1); personLibImg.setCertificateNo(bo.getIdCardNumber()); personLibImg.setResidentPersonId(bo.getId()); + personLibImg.setImgMd5Value(md5); sisPersonLibImgService.insertByBo(personLibImg); log.info("写入安防人像信息完成"); } + /** + * 直接计算字节数组的MD5值 + * + * @param data 图片的字节数组 + * @return 32位小写MD5字符串 + */ + private 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(); + } + /** * 修改授权记录 * @@ -143,10 +192,24 @@ public class SisAuthRecordServiceImpl implements ISisAuthRecordService { * @return 是否修改成功 */ @Override - public Boolean updateByBo(SisAuthRecordBo bo) { - SisAuthRecord update = MapstructUtils.convert(bo, SisAuthRecord.class); - validEntityBeforeSave(update); - return baseMapper.updateById(update) > 0; + public Boolean updateByBo(RemotePersonAuth bo) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.eq(SisAuthRecord::getTargetId, bo.getId()); + boolean flag = baseMapper.delete(lqw) > 0; + Assert.isTrue(flag, "删除授权记录失败"); + + // 删除人像库图片 + SisPersonLibImgVo imgVo = sisPersonLibImgService.queryByPersonId(bo.getId()); + if (imgVo != null) { + flag = sisPersonLibImgService.deleteWithValidByIds(List.of(imgVo.getId()), false); + Assert.isTrue(flag, "删除人像库图片失败"); + } + + // 删除e8人员 + flag = e8PlatformApi.deleteCustomer(bo.getE8Id()); + Assert.isTrue(flag, "删除e8人员失败"); + + return flag; } /** diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisPersonLibImgServiceImpl.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisPersonLibImgServiceImpl.java index 6a18844a..4c70b61a 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisPersonLibImgServiceImpl.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisPersonLibImgServiceImpl.java @@ -118,6 +118,8 @@ public class SisPersonLibImgServiceImpl implements ISisPersonLibImgService { @Transactional(rollbackFor = Exception.class) public Boolean insertByBo(SisPersonLibImgBo bo) { SisPersonLibImg add = MapstructUtils.convert(bo, SisPersonLibImg.class); + assert add != null; + add.setTenantId("000000"); Assert.notNull(add, "数据处理失败"); boolean flag = baseMapper.insert(add) > 0; Assert.isTrue(flag, "新增数据失败"); @@ -165,7 +167,7 @@ public class SisPersonLibImgServiceImpl implements ISisPersonLibImgService { boolean flag = baseMapper.deleteByIds(ids) > 0; Assert.isTrue(flag, "删除失败"); - return true; + return flag; } /** @@ -182,16 +184,47 @@ public class SisPersonLibImgServiceImpl implements ISisPersonLibImgService { /** * 根据入驻员工id,更新huaweiBoxId * - * @param personId 入驻员工id + * @param personId 入驻员工id * @param huaweiBoxId 华为盒子图像id + * @param imgMd5 图片md5值 * @return Boolean */ @Override - public Boolean updateByPersonId(Long personId, Long huaweiBoxId){ + public Boolean updateByPersonId(Long personId, Long huaweiBoxId, String imgMd5) { LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); lqw.eq(SisPersonLibImg::getResidentPersonId, personId); SisPersonLibImg update = new SisPersonLibImg(); update.setRemoteImgId(huaweiBoxId); + update.setImgMd5Value(imgMd5); return baseMapper.update(update, lqw) > 0; } + + /** + * 根据图片MD5,查询图片 + * + * @param imgMd5 图片MD5 + */ + @Override + public SisPersonLibImgVo queryByImgMd5(String imgMd5) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.eq(SisPersonLibImg::getImgMd5Value, imgMd5); + List list = baseMapper.selectVoList(lqw); + if (list.isEmpty()) { + return null; + } else { + return list.get(0); + } + } + + /** + * 根据入驻员工id,查询图片 + * + * @param personId 入驻员工id + */ + @Override + public SisPersonLibImgVo queryByPersonId(Long personId) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.eq(SisPersonLibImg::getResidentPersonId, personId); + return baseMapper.selectVoOne(lqw); + } } 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 index c692e72c..901f54cc 100644 --- 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 @@ -30,6 +30,7 @@ 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; @@ -68,7 +69,7 @@ public class AuthSyncTask { // 需要先设置模拟上下文 SaTokenContextMockUtil.setMockContext(() -> { // 模拟登录 - StpUtil.login(1); // 模拟登录 + StpUtil.login(1); unAuthPersonRef.set(remoteResidentPersonService.queryUnAuthPerson()); List unAuthPerson = unAuthPersonRef.get(); @@ -89,12 +90,25 @@ public class AuthSyncTask { byte[] imgByte = imgByteRef.get(); if (imgByte == null) continue; - // 写入华为盒子 - Long huaweiId = syncHuaweiBox(person, imgByte); + 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) continue; // 更新人像信息huaweiBoxId - Boolean update = sisPersonLibImgService.updateByPersonId(person.getId(), huaweiId); + update = sisPersonLibImgService.updateByPersonId(person.getId(), huaweiId, nowMd5); if (!update) continue; // 同步E8平台 @@ -105,7 +119,6 @@ public class AuthSyncTask { remoteResidentPersonService.updateE8Id(person.getId(), e8Id); } - } else { log.info("无待授权人员"); } @@ -115,12 +128,18 @@ public class AuthSyncTask { }); } + /** + * 补录授权记录 + * + * @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()); @@ -130,6 +149,13 @@ public class AuthSyncTask { log.info("补录授权记录、人像信息完成"); } + /** + * 同步华为盒子 + * + * @param vo bean + * @param imgByte 图片字节 + * @return Long + */ private Long syncHuaweiBox(RemoteResidentPersonVo vo, byte[] imgByte) { log.info("开始写入华为平台"); AddHWPersonReq req = new AddHWPersonReq(); @@ -149,6 +175,13 @@ public class AuthSyncTask { return pId; } + /** + * 同步E8平台 + * + * @param vo bean + * @param imgByte 图片字节 + * @return Long + */ private Long syncE8Plat(RemoteResidentPersonVo vo, byte[] imgByte) { log.info("e8平台上传照片"); @@ -205,4 +238,35 @@ public class AuthSyncTask { } 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(); + } } diff --git a/ruoyi-modules/Sis/src/main/resources/mapper/sis/SisAuthRecordMapper.xml b/ruoyi-modules/Sis/src/main/resources/mapper/sis/SisAuthRecordMapper.xml index d2481576..eb980241 100644 --- a/ruoyi-modules/Sis/src/main/resources/mapper/sis/SisAuthRecordMapper.xml +++ b/ruoyi-modules/Sis/src/main/resources/mapper/sis/SisAuthRecordMapper.xml @@ -7,7 +7,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"