设备核查计划:设备档案变更即时登记计划明细,提前核查复用待核查明细并回写档案,已完成记录不可覆盖;新增附件字段、明细固定排序与删除保护;人员查询新增包含admin的类型;检验保存/提交按页面模板校验,复核驳回按检验室删除复核人
已修改10个文件
333 ■■■■■ 文件已修改
cnas-device/src/main/java/com/ruoyi/device/controller/DeviceExaminePlanController.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-device/src/main/java/com/ruoyi/device/pojo/DeviceExaminePlanDetails.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-device/src/main/java/com/ruoyi/device/service/DeviceExaminePlanService.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceExaminePlanServiceImpl.java 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceServiceImpl.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-device/src/main/resources/mapper/DeviceExaminePlanDetailsMapper.xml 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderPlanServiceImpl.java 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/UserMapper.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/UserServiceImpl.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/UserMapper.xml 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-device/src/main/java/com/ruoyi/device/controller/DeviceExaminePlanController.java
@@ -168,17 +168,27 @@
    @Operation(summary = "修改设备核查计划详情")
    @PostMapping("/updateDeviceExaminePlanDetail")
    public Result updateDeviceExaminePlanDetail(@RequestBody DeviceExaminePlanDetails deviceExaminePlanDetail){
        return Result.success(deviceExaminePlanDetailsService.updateById(deviceExaminePlanDetail));
        return Result.success(deviceExaminePlanService.updateExaminePlanDetail(deviceExaminePlanDetail));
    }
    /**
     * 删除设备核查计划详情
     * 删除设备核查计划详情(已有核查记录的不允许删除)
     * @return
     */
    @Operation(summary = "删除设备核查计划详情")
    @DeleteMapping("/delDeviceExaminePlanDetail")
    public Result delDeviceExaminePlanDetail(Integer planDetailsId){
        return Result.success(deviceExaminePlanDetailsService.removeById(planDetailsId));
        return Result.success(deviceExaminePlanService.removeExaminePlanDetail(planDetailsId));
    }
    /**
     * 为指定设备找一条可录入核查记录的计划明细,没有则新增本轮明细
     * @return
     */
    @Operation(summary = "按设备获取本轮核查计划明细")
    @GetMapping("/resolveExaminePlanDetail")
    public Result<DeviceExaminePlanDetails> resolveExaminePlanDetail(Integer deviceId, String checkTime){
        return Result.success(deviceExaminePlanService.resolveExaminePlanDetail(deviceId, checkTime));
    }
    /**
cnas-device/src/main/java/com/ruoyi/device/pojo/DeviceExaminePlanDetails.java
@@ -57,6 +57,12 @@
    @Schema(description = "备注")
    private String remark;
    @Schema(description = "附件名称")
    private String fileName;
    @Schema(description = "附件路径")
    private String fileUrl;
    @Schema(description = "创建人")
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
cnas-device/src/main/java/com/ruoyi/device/service/DeviceExaminePlanService.java
@@ -96,14 +96,36 @@
    DeviceExaminePlanDto getOrCreatePlanByYear(String planYear);
    /**
     * 设备档案变更后,把设备同步到对应年份的设备核查计划明细(仅当已进入提醒期/已过期时生成)
     * 设备档案变更后,立即把设备登记到下次核查日期所在年份的设备核查计划明细
     * @param device 设备
     */
    void syncDeviceExamineDetail(Device device);
    /**
     * 核查记录复核通过后,滚动设备档案的最近/下次核查日期
     * 核查记录复核通过后,滚动设备档案的最近/下次核查日期,并登记下一轮计划
     * @param planDetailsId 计划明细id
     */
    void updateDeviceExamineDate(Integer planDetailsId);
    /**
     * 为指定设备找一条可录入核查记录的计划明细,没有则新增本轮明细
     * @param deviceId 设备id
     * @param checkTime 核查月份(yyyy-MM),决定明细所属的计划年份
     * @return 计划明细
     */
    DeviceExaminePlanDetails resolveExaminePlanDetail(Integer deviceId, String checkTime);
    /**
     * 修改计划明细(核查月份跨年时归到对应年份的计划)
     * @param detail 计划明细
     * @return 是否修改成功
     */
    boolean updateExaminePlanDetail(DeviceExaminePlanDetails detail);
    /**
     * 删除计划明细(已有核查记录的不允许删除)
     * @param planDetailsId 计划明细id
     * @return 是否删除成功
     */
    boolean removeExaminePlanDetail(Integer planDetailsId);
}
cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceExaminePlanServiceImpl.java
@@ -22,10 +22,14 @@
import com.ruoyi.device.excel.upload.DeviceExaminePlanUpload;
import com.ruoyi.device.mapper.DeviceExaminePlanDetailsMapper;
import com.ruoyi.device.mapper.DeviceExaminePlanMapper;
import com.ruoyi.device.mapper.DeviceExamineRecordContrastMapper;
import com.ruoyi.device.mapper.DeviceExamineRecordMapper;
import com.ruoyi.device.mapper.DeviceMapper;
import com.ruoyi.device.pojo.Device;
import com.ruoyi.device.pojo.DeviceExaminePlan;
import com.ruoyi.device.pojo.DeviceExaminePlanDetails;
import com.ruoyi.device.pojo.DeviceExamineRecord;
import com.ruoyi.device.pojo.DeviceExamineRecordContrast;
import com.ruoyi.device.service.DeviceExaminePlanDetailsService;
import com.ruoyi.device.service.DeviceExaminePlanService;
import com.ruoyi.framework.exception.ErrorException;
@@ -49,6 +53,7 @@
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -77,6 +82,10 @@
    private DeviceMapper deviceMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private DeviceExamineRecordMapper deviceExamineRecordMapper;
    @Resource
    private DeviceExamineRecordContrastMapper deviceExamineRecordContrastMapper;
    /**
     * 新增设备核查计划
@@ -381,15 +390,15 @@
    }
    /**
     * 设备档案变更后,把设备同步到对应年份的设备核查计划明细
     * 设备档案变更后,立即把设备登记到下次核查日期所在年份的设备核查计划明细
     */
    @Override
    public void syncDeviceExamineDetail(Device device) {
        LocalDate remind = calcExamineRemindDate(device);
        if (remind == null || remind.isAfter(LocalDate.now())) {
        LocalDate due = calcExamineDueDate(device);
        if (due == null) {
            return;
        }
        DeviceExaminePlan plan = getOrCreatePlanEntity(String.valueOf(remind.getYear()));
        DeviceExaminePlan plan = getOrCreatePlanEntity(String.valueOf(due.getYear()));
        fillExamineDetailIfAbsent(plan, device);
    }
@@ -406,6 +415,7 @@
        if (device == null) {
            return;
        }
        // 提前核查时计划月份可能还没到,取实际完成当天;否则按本轮计划核查月份
        LocalDate checkDate = parseCheckDate(detail.getCheckTime());
        if (checkDate.isAfter(LocalDate.now())) {
            checkDate = LocalDate.now();
@@ -423,6 +433,8 @@
            }
        }
        deviceMapper.updateById(device);
        // 本轮核查完成后立即登记下一轮,历史明细和记录保持不动
        syncDeviceExamineDetail(device);
    }
    /**
@@ -445,7 +457,7 @@
    }
    /**
     * 扫描所有设备,把已到点(下次核查日期前1个月起,含已过期)的设备补进本年度计划
     * 扫描所有设备,把本年度及往年逾期未核查的设备补进计划
     */
    private void ensureExamineDetails(DeviceExaminePlan plan) {
        List<Device> devices = deviceMapper.selectList(null);
@@ -455,9 +467,9 @@
    }
    /**
     * 设备提醒起点:下次核查日期前1个月(没填下次日期时用最近日期+核查周期兜底)
     * 设备本轮应核查日期(没填下次日期时用最近日期+核查周期兜底)
     */
    private LocalDate calcExamineRemindDate(Device device) {
    private LocalDate calcExamineDueDate(Device device) {
        LocalDateTime base = device.getNextExamineDate();
        if (base == null && device.getLastExamineDate() != null && StringUtils.isNotBlank(device.getExamineCycle())) {
            try {
@@ -465,21 +477,21 @@
            } catch (NumberFormatException ignored) {
            }
        }
        return base == null ? null : base.toLocalDate().minusMonths(1);
        return base == null ? null : base.toLocalDate();
    }
    /**
     * 已到点且计划中尚无该设备本轮明细时自动补一条
     * 计划中尚无该设备本轮明细时自动补一条;核查时间取应核查月份
     */
    private void fillExamineDetailIfAbsent(DeviceExaminePlan plan, Device device) {
        LocalDate remind = calcExamineRemindDate(device);
        if (remind == null || remind.isAfter(LocalDate.now())) {
        LocalDate due = calcExamineDueDate(device);
        if (due == null) {
            return;
        }
        if (plan.getPlanYear() != null && String.valueOf(remind.getYear()).compareTo(plan.getPlanYear()) > 0) {
        if (plan.getPlanYear() != null && String.valueOf(due.getYear()).compareTo(plan.getPlanYear()) > 0) {
            return;
        }
        String checkTime = remind.format(DateTimeFormatter.ofPattern("yyyy-MM"));
        String checkTime = due.format(DateTimeFormatter.ofPattern("yyyy-MM"));
        Long exist = deviceExaminePlanDetailsMapper.selectCount(Wrappers.<DeviceExaminePlanDetails>lambdaQuery()
                .eq(DeviceExaminePlanDetails::getPlanId, plan.getPlanId())
                .eq(DeviceExaminePlanDetails::getDeviceId, device.getId())
@@ -515,4 +527,122 @@
        }
        return LocalDate.now();
    }
    /**
     * 为指定设备找一条可录入核查记录的计划明细;没有可用明细时在当前年度计划新增本轮明细
     */
    @Override
    public DeviceExaminePlanDetails resolveExaminePlanDetail(Integer deviceId, String checkTime) {
        if (deviceId == null) {
            throw new ErrorException("请选择核查设备");
        }
        Device device = deviceMapper.selectById(deviceId);
        if (device == null) {
            throw new ErrorException("核查设备不存在");
        }
        String checkMonth = normalizeCheckMonth(checkTime);
        DeviceExaminePlan plan = getOrCreatePlanEntity(checkMonth.substring(0, 4));
        List<DeviceExaminePlanDetails> details = deviceExaminePlanDetailsMapper.selectList(
                Wrappers.<DeviceExaminePlanDetails>lambdaQuery()
                        .eq(DeviceExaminePlanDetails::getDeviceId, deviceId)
                        .orderByAsc(DeviceExaminePlanDetails::getCheckTime));
        DeviceExaminePlanDetails nearest = null;
        long nearestDistance = Long.MAX_VALUE;
        for (DeviceExaminePlanDetails detail : details) {
            // 已有核查记录的明细代表已完成的一轮,后续核查永远不复用、不覆盖
            Long recordCount = deviceExamineRecordMapper.selectCount(Wrappers.<DeviceExamineRecord>lambdaQuery()
                    .eq(DeviceExamineRecord::getPlanDetailsId, detail.getPlanDetailsId()));
            if (recordCount != null && recordCount > 0) {
                continue;
            }
            if (detail.getPlanId() != null && detail.getPlanId().equals(plan.getPlanId())) {
                return detail;
            }
            long distance = monthDistance(detail.getCheckTime(), checkMonth);
            if (distance < nearestDistance) {
                nearest = detail;
                nearestDistance = distance;
            }
        }
        // 提前核查时优先复用系统登记、尚未核查的这一轮(可能在别的年份计划里)
        if (nearest != null) {
            return nearest;
        }
        DeviceExaminePlanDetails detail = new DeviceExaminePlanDetails();
        detail.setPlanId(plan.getPlanId());
        detail.setDeviceId(device.getId());
        String deviceName = device.getDeviceName() == null ? "" : device.getDeviceName();
        if (StringUtils.isNotBlank(device.getSpecificationModel())) {
            deviceName = deviceName + " " + device.getSpecificationModel();
        }
        detail.setDeviceName(deviceName);
        detail.setDeviceNumber(device.getManagementNumber());
        detail.setCheckTime(checkMonth);
        deviceExaminePlanDetailsMapper.insert(detail);
        return detail;
    }
    /**
     * 规范核查月份为 yyyy-MM,非法或为空时取当前月份
     */
    private String normalizeCheckMonth(String checkTime) {
        if (StringUtils.isNotBlank(checkTime)) {
            String normalized = checkTime.trim().replace('.', '-').replace('/', '-');
            if (normalized.length() >= 7) {
                try {
                    return YearMonth.parse(normalized.substring(0, 7)).toString();
                } catch (Exception ignored) {
                }
            }
        }
        return LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM"));
    }
    /**
     * 两个月份之间相差的月数
     */
    private long monthDistance(String fromCheckTime, String targetMonth) {
        try {
            YearMonth from = YearMonth.parse(normalizeCheckMonth(fromCheckTime));
            YearMonth target = YearMonth.parse(targetMonth);
            return Math.abs(ChronoUnit.MONTHS.between(from, target));
        } catch (Exception e) {
            return Long.MAX_VALUE;
        }
    }
    /**
     * 修改计划明细;核查月份跨年时,把明细归到核查月份所属年份的计划下
     */
    @Override
    public boolean updateExaminePlanDetail(DeviceExaminePlanDetails detail) {
        if (detail == null || detail.getPlanDetailsId() == null) {
            throw new ErrorException("缺少设备核查计划明细id");
        }
        if (StringUtils.isNotBlank(detail.getCheckTime())) {
            String checkMonth = normalizeCheckMonth(detail.getCheckTime());
            detail.setCheckTime(checkMonth);
            DeviceExaminePlan plan = getOrCreatePlanEntity(checkMonth.substring(0, 4));
            detail.setPlanId(plan.getPlanId());
        }
        return deviceExaminePlanDetailsMapper.updateById(detail) > 0;
    }
    /**
     * 删除计划明细;已有核查/比对记录的不允许删除,保证历史留档
     */
    @Override
    public boolean removeExaminePlanDetail(Integer planDetailsId) {
        if (planDetailsId == null) {
            throw new ErrorException("缺少设备核查计划明细id");
        }
        Long recordCount = deviceExamineRecordMapper.selectCount(Wrappers.<DeviceExamineRecord>lambdaQuery()
                .eq(DeviceExamineRecord::getPlanDetailsId, planDetailsId));
        Long contrastCount = deviceExamineRecordContrastMapper.selectCount(Wrappers.<DeviceExamineRecordContrast>lambdaQuery()
                .eq(DeviceExamineRecordContrast::getPlanDetailsId, planDetailsId));
        if ((recordCount != null && recordCount > 0) || (contrastCount != null && contrastCount > 0)) {
            throw new ErrorException("该计划已存在核查记录,为保留历史记录不允许删除");
        }
        return deviceExaminePlanDetailsService.removeById(planDetailsId);
    }
}
cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceServiceImpl.java
@@ -102,7 +102,13 @@
    @Override
    public int addDeviceParameter(Device itemParameter) {
        return deviceMapper.insert(itemParameter);
        int rows = deviceMapper.insert(itemParameter);
        Device device = deviceMapper.selectById(itemParameter.getId());
        if (device != null && (device.getNextExamineDate() != null
                || (device.getLastExamineDate() != null && StringUtils.isNotBlank(device.getExamineCycle())))) {
            deviceExaminePlanService.syncDeviceExamineDetail(device);
        }
        return rows;
    }
    @Override
cnas-device/src/main/resources/mapper/DeviceExaminePlanDetailsMapper.xml
@@ -20,6 +20,8 @@
            CASE WHEN d.check_charger_user='' or d.check_charger_user is null THEN u.name
                ELSE d.check_charger_user END AS check_charger_user,
            d.remark,
            d.file_name,
            d.file_url,
            d.create_user,
            d.create_time,
            d.update_user,
@@ -43,11 +45,11 @@
        left join device_examine_record dc on d.plan_details_id = dc.plan_details_id
        left join device_examine_record_contrast dd on dd.plan_details_id = d.plan_details_id
        left join device dev on dev.id = d.device_id
        order by check_time asc
        ) a
        <if test="ew.customSqlSegment != null and ew.customSqlSegment != ''">
            ${ew.customSqlSegment}
        </if>
        order by device_number asc, check_time desc
    </select>
</mapper>
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderPlanServiceImpl.java
@@ -365,7 +365,7 @@
                }
            }
            map.put("errorMsg", collect);
            map.put("missingExportItems", getMissingTemplateExportValues(orderId));
            map.put("missingExportItems", getMissingTemplateExportValues(orderId, laboratory));
            map.put("unInsOrderCount", 0L);
            return map;
        }
@@ -649,10 +649,11 @@
        JSONObject values = JSON.parseObject(JSON.toJSONString(dto.getValues() == null
                ? Collections.emptyMap() : dto.getValues()));
        // 检验期间页面展示的是标准维护中的最新模板,保存校验必须使用同一份模板,
        // 避免模板新增“导出值”批注后仍按下单时的旧快照误报未配置。
        String currentTemplateThing = getCurrentTemplateThing(snapshot);
        List<String> exportValueCoordinates = getExportValueCoordinates(currentTemplateThing).values().stream()
        // 保存时必须使用页面当前展示的模板:待检、在检阶段展示标准维护中的实时模板,
        // 复核、驳回阶段展示订单快照;否则模板在检验途中被修改后会取错导出值单元格。
        boolean useSnapshot = useSnapshotTemplate(dto.getOrderId(), getCurrentUserLaboratory(dto.getOrderId()));
        String pageTemplateThing = getPageTemplateThing(snapshot, useSnapshot);
        List<String> exportValueCoordinates = getExportValueCoordinates(pageTemplateThing).values().stream()
                .flatMap(Collection::stream)
                .distinct()
                .collect(Collectors.toList());
@@ -889,8 +890,8 @@
    }
    /**
     * 检验保存、提交校验读取标准维护中的实时模板;模板已被删除或内容为空时才回退订单快照。
     * 检验完成后的展示和报告仍由订单快照负责,不会随标准模板后续修改而变化。
     * 读取标准维护中的实时模板;模板已被删除或内容为空时才回退订单快照。
     * 仅用于检验室仍处于待检、在检阶段(页面展示实时模板)的保存与校验。
     */
    private String getCurrentTemplateThing(InsOrderStandardTemplate snapshot) {
        if (snapshot != null && snapshot.getTemplateId() != null) {
@@ -903,9 +904,53 @@
    }
    /**
     * 检验单页面在检验室进入复核及之后状态时展示订单快照,导出值的保存和提交校验必须与页面
     * 使用同一份模板;否则标准模板在检验途中被修改后,历史单据会按新坐标读取快照数据而误报为空。
     */
    private String getPageTemplateThing(InsOrderStandardTemplate snapshot, boolean useSnapshot) {
        if (useSnapshot && snapshot != null && StrUtil.isNotBlank(snapshot.getThing())) {
            return snapshot.getThing();
        }
        return getCurrentTemplateThing(snapshot);
    }
    /**
     * 与检验单页面 getTemplateThing 的判定保持一致:检验室状态进入复核(2)及之后时使用订单快照。
     * 指派记录里的实验室名称可能和状态行不一致(如“全部”),此时退回按订单整体状态判定。
     */
    private boolean useSnapshotTemplate(Integer orderId, String laboratory) {
        if (StringUtils.isNotBlank(laboratory)) {
            InsOrderState state = insOrderStateMapper.selectOne(Wrappers.<InsOrderState>lambdaQuery()
                    .eq(InsOrderState::getInsOrderId, orderId)
                    .eq(InsOrderState::getLaboratory, laboratory)
                    .last("limit 1"));
            if (state != null) {
                return state.getInsState() != null && state.getInsState() >= 2;
            }
        }
        return insOrderStateMapper.selectList(Wrappers.<InsOrderState>lambdaQuery()
                        .eq(InsOrderState::getInsOrderId, orderId))
                .stream()
                .anyMatch(state -> state.getInsState() != null && state.getInsState() >= 2);
    }
    /**
     * 取当前登录人在该订单上最近一条指派记录所属的检验室;未指派账号返回 null,由状态判定兜底。
     */
    private String getCurrentUserLaboratory(Integer orderId) {
        Integer userId = SecurityUtils.getUserId().intValue();
        InsSampleUser sampleUser = insSampleUserMapper.selectOne(Wrappers.<InsSampleUser>lambdaQuery()
                .eq(InsSampleUser::getInsSampleId, orderId)
                .eq(InsSampleUser::getUserId, userId)
                .orderByDesc(InsSampleUser::getId)
                .last("limit 1"));
        return sampleUser == null ? null : sampleUser.getSonLaboratory();
    }
    /**
     * 直绑模板订单只校验每个“导出值”批注所在区域右侧紧邻单元格,不使用检验项状态或 last_value 判定。
     */
    private List<String> getMissingTemplateExportValues(Integer orderId) {
    private List<String> getMissingTemplateExportValues(Integer orderId, String laboratory) {
        List<InsOrderStandardTemplate> snapshots = insOrderStandardTemplateService.list(
                Wrappers.<InsOrderStandardTemplate>lambdaQuery()
                        .eq(InsOrderStandardTemplate::getInsOrderId, orderId)
@@ -915,9 +960,10 @@
            missing.add("当前订单未找到原始记录模板快照");
            return missing;
        }
        boolean useSnapshot = useSnapshotTemplate(orderId, laboratory);
        for (InsOrderStandardTemplate snapshot : snapshots) {
            Integer templateId = snapshot.getTemplateId();
            List<String> coordinates = getExportValueCoordinates(getCurrentTemplateThing(snapshot)).values().stream()
            List<String> coordinates = getExportValueCoordinates(getPageTemplateThing(snapshot, useSnapshot)).values().stream()
                    .flatMap(Collection::stream)
                    .distinct()
                    .collect(Collectors.toList());
@@ -1273,7 +1319,7 @@
        boolean directTemplateOrder = isDirectTemplateOrder(orderId);
        List<InsProduct> insProducts;
        if (directTemplateOrder) {
            List<String> missingExportValues = getMissingTemplateExportValues(orderId);
            List<String> missingExportValues = getMissingTemplateExportValues(orderId, laboratory);
            if (!missingExportValues.isEmpty()) {
                throw new ErrorException("模板中的导出值不能为空:\n" + String.join("\n", missingExportValues));
            }
@@ -1882,9 +1928,17 @@
        } else {
            //复核不通过将把复核的负责人去掉
            Integer id = insSampleUserMapper.selectOne(Wrappers.<InsSampleUser>lambdaQuery().eq(InsSampleUser::getInsSampleId, orderId).orderByDesc(InsSampleUser::getId).last("limit 1")).getId();
            insSampleUserMapper.deleteById(id);
            // 复核不通过只去掉本检验室本次提交的复核负责人;按复核人状态和检验室定位,
            // 避免误删其他检验室的记录或检验人员记录。
            InsSampleUser reviewerRow = insSampleUserMapper.selectOne(Wrappers.<InsSampleUser>lambdaQuery()
                    .eq(InsSampleUser::getInsSampleId, orderId)
                    .eq(InsSampleUser::getState, 1)
                    .eq(InsSampleUser::getSonLaboratory, laboratory)
                    .orderByDesc(InsSampleUser::getId)
                    .last("limit 1"));
            if (reviewerRow != null) {
                insSampleUserMapper.deleteById(reviewerRow.getId());
            }
            // 当前审核人
            Integer currentUserId = SecurityUtils.getUserId().intValue();
ruoyi-system/src/main/java/com/ruoyi/system/mapper/UserMapper.java
@@ -26,6 +26,13 @@
    List<User> selectUserCondition(@Param("ew") QueryWrapper<User> ew, @Param("type") String type);
    /**
     * 根据条件获取用户列表(包含超级管理员)
     * @param ew
     * @return
     */
    List<User> selectUserConditionWithAdmin(@Param("ew") QueryWrapper<User> ew);
    /**
     * 获取用户部门
     * @param userId
     * @return
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/UserServiceImpl.java
@@ -43,6 +43,8 @@
                    return baseMapper.selectDepartmentLimsUserList(SecurityUtils.getUserId().intValue());
                case "3":
                    return baseMapper.selectInspectorUserList();
                case "4":
                    return baseMapper.selectUserConditionWithAdmin(QueryWrappers.queryWrappers(user));
            }
        }
ruoyi-system/src/main/resources/mapper/system/UserMapper.xml
@@ -31,6 +31,34 @@
        </if>
    </select>
    <!--根据条件获取用户列表(包含超级管理员)-->
    <select id="selectUserConditionWithAdmin" resultType="com.ruoyi.common.core.domain.entity.User">
        select * from (select id,
        dept_id,
        account,
        name,
        name_en,
        user_type,
        email,
        phone,
        sex,
        age,
        signature_url,
        picture_url,
        status,
        del_flag,
        login_ip,
        login_date,
        depart_lims_id,
        company,
        is_custom
        from user
        where del_flag = '0') a
        <if test="ew.customSqlSegment != null and ew.customSqlSegment != ''">
            ${ew.customSqlSegment}
        </if>
    </select>
    <!-- 获取用户部门 -->
    <select id="selectUserDepartmentLimsName" resultType="java.lang.String">
        select dl.name