zhaowenyu
2025-10-31 ddf364ed076204206fbba47f2947b30cbbd21ecb
Merge remote-tracking branch 'origin/dev' into dev
2 files added
3 files modified
253 ■■■■■ changed files
ard-admin/src/main/java/com/ard/web/controller/sample/DeviceController.java 50 ●●●●● patch | view | raw | blame | history
ard-common/src/main/java/com/ard/common/annotation/DataScopePlus.java 29 ●●●●● patch | view | raw | blame | history
ard-framework/src/main/java/com/ard/framework/aspectj/DataScopePlusAspect.java 136 ●●●●● patch | view | raw | blame | history
ard-sample/src/main/java/com/ard/sample/manage/service/IDeviceService.java 5 ●●●●● patch | view | raw | blame | history
ard-sample/src/main/java/com/ard/sample/manage/service/impl/DeviceServiceImpl.java 33 ●●●●● patch | view | raw | blame | history
ard-admin/src/main/java/com/ard/web/controller/sample/DeviceController.java
@@ -1,5 +1,8 @@
package com.ard.web.controller.sample;
import com.ard.common.core.controller.BaseController;
import com.ard.common.core.page.TableDataInfo;
import com.ard.device.camera.domain.ArdCamera;
import com.ard.sample.common.error.CommonErrorEnum;
import com.ard.sample.common.model.PaginationData;
import com.ard.sample.common.model.ResponseResult;
@@ -8,19 +11,27 @@
import com.ard.sample.component.mqtt.model.CommonTopicResponse;
import com.ard.sample.manage.model.dto.DeviceDTO;
import com.ard.sample.manage.model.dto.DeviceFirmwareUpgradeDTO;
import com.ard.sample.manage.model.entity.DeviceEntity;
import com.ard.sample.manage.model.enums.DeviceFirmwareStatusEnum;
import com.ard.sample.manage.model.enums.DeviceSetPropertyEnum;
import com.ard.sample.manage.model.receiver.StatusGatewayReceiver;
import com.ard.sample.manage.service.IDeviceService;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.JsonNode;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.time.ZoneId;
import java.util.List;
import java.util.Optional;
import static com.ard.common.utils.PageUtils.startPage;
/**
 * @author sean.zhou
@@ -31,7 +42,7 @@
@RestController
@Slf4j
@RequestMapping("/dock/device")
public class DeviceController {
public class DeviceController extends BaseController {
    @Autowired
    private IDeviceService deviceService;
@@ -202,4 +213,41 @@
        deviceService.devicePropertySet(dockSn, propertyEnumOpt.get(), param.get(property));
        return ResponseResult.success();
    }
    /**
     * 查询机场设备列表
     */
    @PreAuthorize("@ss.hasPermi('device:camera:list')")
    @GetMapping("/test/list")
    @ApiOperation("查询机场设备列表")
    public TableDataInfo list(DeviceDTO device) {
        startPage();
        DeviceEntity deviceEntity = deviceDTO2Entity(device);
        QueryWrapper<DeviceEntity> queryWrapper=new QueryWrapper<>(deviceEntity);
        List<DeviceEntity> list = deviceService.selectList(queryWrapper);
        return getDataTable(list);
    }
    private DeviceEntity deviceDTO2Entity(DeviceDTO dto) {
        DeviceEntity.DeviceEntityBuilder builder = DeviceEntity.builder();
        if (dto == null) {
            return builder.build();
        }
        return builder.deviceSn(dto.getDeviceSn())
                .userId(dto.getUserId())
                .nickname(dto.getNickname())
                .boundStatus(dto.getBoundStatus())
                .loginTime(dto.getLoginTime() != null ?
                        dto.getLoginTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() : null)
                .boundTime(dto.getBoundTime() != null ?
                        dto.getBoundTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() : null)
                .childSn(dto.getChildDeviceSn())
                .domain(dto.getDomain())
                .firmwareVersion(dto.getFirmwareVersion())
                .workType(dto.getWorkType())
                .compatibleStatus(dto.getFirmwareStatus() == null ? null :
                        DeviceFirmwareStatusEnum.CONSISTENT_UPGRADE != DeviceFirmwareStatusEnum.find(dto.getFirmwareStatus()))
                .build();
    }
}
ard-common/src/main/java/com/ard/common/annotation/DataScopePlus.java
New file
@@ -0,0 +1,29 @@
package com.ard.common.annotation;
import java.lang.annotation.*;
/**
 * 数据权限过滤注解
 *
 * @author ard
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataScopePlus
{
    /**
     * 部门表的别名
     */
    public String deptAlias() default "";
    /**
     * 用户表的别名
     */
    public String userAlias() default "";
    /**
     * 权限字符(用于多个角色匹配符合要求的权限)默认根据权限注解@ss获取,多个权限用逗号分隔开来
     */
    public String permission() default "";
}
ard-framework/src/main/java/com/ard/framework/aspectj/DataScopePlusAspect.java
New file
@@ -0,0 +1,136 @@
package com.ard.framework.aspectj;
import com.ard.common.annotation.DataScopePlus;
import com.ard.common.constant.UserConstants;
import com.ard.common.core.domain.entity.SysRole;
import com.ard.common.core.domain.entity.SysUser;
import com.ard.common.core.domain.model.LoginUser;
import com.ard.common.core.text.Convert;
import com.ard.common.utils.SecurityUtils;
import com.ard.common.utils.StringUtils;
import com.ard.framework.security.context.PermissionContextHolder;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Aspect
@Component
public class DataScopePlusAspect {
    /**
     * 全部数据权限
     */
    public static final String DATA_SCOPE_ALL = "1";
    /**
     * 自定数据权限
     */
    public static final String DATA_SCOPE_CUSTOM = "2";
    /**
     * 部门数据权限
     */
    public static final String DATA_SCOPE_DEPT = "3";
    /**
     * 部门及以下数据权限
     */
    public static final String DATA_SCOPE_DEPT_AND_CHILD = "4";
    /**
     * 仅本人数据权限
     */
    public static final String DATA_SCOPE_SELF = "5";
    @Pointcut("@annotation(com.ard.common.annotation.DataScopePlus)")
    public void dataScopePointcut() {
    }
    @Before("@annotation(controllerDataScopePlus)")
    public void doBefore(JoinPoint joinPoint, DataScopePlus controllerDataScopePlus) {
        handleDataScope(joinPoint, controllerDataScopePlus);
    }
    protected void handleDataScope(final JoinPoint joinPoint, DataScopePlus controllerDataScope) {
        // 获取当前用户
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (StringUtils.isNotNull(loginUser)) {
            SysUser currentUser = loginUser.getUser();
            if (currentUser != null && !currentUser.isAdmin()) {
                String permission = StringUtils.defaultIfEmpty(controllerDataScope.permission(),
                        PermissionContextHolder.getContext());
                dataScopeFilter(joinPoint, currentUser, permission);
            }
        }
    }
    private void dataScopeFilter(JoinPoint joinPoint, SysUser user, String permission) {
        StringBuilder sqlString = new StringBuilder();
        List<String> conditions = new ArrayList<>();
        List<String> scopeCustomIds = new ArrayList<>();
        // 获取用户角色并遍历进行权限检查
        user.getRoles().forEach(role -> {
            if (DATA_SCOPE_CUSTOM.equals(role.getDataScope()) && StringUtils.equals(role.getStatus(),
                    UserConstants.ROLE_NORMAL)) {
                if (StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission))) {
                    scopeCustomIds.add(Convert.toStr(role.getRoleId()));
                }
            }
        });
        for (SysRole role : user.getRoles()) {
            String dataScope = role.getDataScope();
            if (conditions.contains(dataScope) || StringUtils.equals(role.getStatus(), UserConstants.ROLE_DISABLE)) {
                continue;
            }
            if (!StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission))) {
                continue;
            }
            if (DATA_SCOPE_ALL.equals(dataScope)) {
                sqlString = new StringBuilder();
                conditions.add(dataScope);
                break;
            } else if (DATA_SCOPE_CUSTOM.equals(dataScope)) {
                // 自定义数据权限
                if (scopeCustomIds.size() > 1) {
                    sqlString.append(StringUtils.format(" OR dept_id IN (SELECT dept_id FROM sys_role_dept WHERE " +
                            "role_id IN ({}) )", String.join(",", scopeCustomIds)));
                } else {
                    sqlString.append(StringUtils.format(" OR dept_id IN (SELECT dept_id FROM sys_role_dept WHERE " +
                            "role_id = {} )", role.getRoleId()));
                }
            } else if (DATA_SCOPE_DEPT.equals(dataScope)) {
                // 部门数据权限
                sqlString.append(StringUtils.format(" OR dept_id = {}", user.getDeptId()));
            } else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope)) {
                // 部门及以下数据权限
                sqlString.append(StringUtils.format(" OR dept_id IN (SELECT dept_id FROM sys_dept WHERE dept_id = {} " +
                        "OR find_in_set({}, ancestors))", user.getDeptId(), user.getDeptId()));
            } else if (DATA_SCOPE_SELF.equals(dataScope)) {
                // 仅本人数据权限
                sqlString.append(StringUtils.format(" OR user_id = {}", user.getUserId()));
            }
            conditions.add(dataScope);
        }
        QueryWrapper<?> queryWrapper = getQueryWrapper(joinPoint);
        if (StringUtils.isNotBlank(sqlString.toString())) {
            queryWrapper.apply(sqlString.substring(4));
        }
    }
    private QueryWrapper<?> getQueryWrapper(JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        if (args != null && args.length > 0 && args[0] instanceof QueryWrapper) {
            return (QueryWrapper<?>) args[0];
        }
        return null;
    }
}
ard-sample/src/main/java/com/ard/sample/manage/service/IDeviceService.java
@@ -8,10 +8,12 @@
import com.ard.sample.manage.model.dto.DeviceDTO;
import com.ard.sample.manage.model.dto.DeviceFirmwareUpgradeDTO;
import com.ard.sample.manage.model.dto.TopologyDeviceDTO;
import com.ard.sample.manage.model.entity.DeviceEntity;
import com.ard.sample.manage.model.enums.DeviceSetPropertyEnum;
import com.ard.sample.manage.model.param.DeviceQueryParam;
import com.ard.sample.manage.model.receiver.FirmwareVersionReceiver;
import com.ard.sample.manage.model.receiver.StatusGatewayReceiver;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.fasterxml.jackson.databind.JsonNode;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
@@ -228,4 +230,7 @@
     * @return
     */
    Boolean checkDeviceOnline(String sn);
    public List<DeviceEntity> selectList(Wrapper<DeviceEntity> queryWrapper);
}
ard-sample/src/main/java/com/ard/sample/manage/service/impl/DeviceServiceImpl.java
@@ -1,7 +1,9 @@
package com.ard.sample.manage.service.impl;
import com.alibaba.fastjson2.JSONObject;
import com.ard.common.annotation.DataScopePlus;
import com.ard.system.authorize.service.AuthorizeService;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -264,7 +266,7 @@
    /**
     * 发布状态回复消息
     *
     * @param sn 序列号
     * @param sn       序列号
     * @param response 通用主题响应对象
     */
    @Override
@@ -312,7 +314,7 @@
    /**
     * 设备列表
     * */
     */
    @Override
    public List<DeviceDTO> getDevicesTopoForWeb() {
        List<DeviceDTO> devicesList = this.getDevicesByParams(
@@ -542,7 +544,7 @@
            return Optional.of(deviceEntity);
        }
        // 2025-10-20 zwy 添加时增加授权验证及数量限制,限制为3台机场设备,超出则抛出异常
        try{
        try {
            // 查询数据库中机器设备数量
            // 根据参数获取设备列表
            List<DeviceDTO> devicesList = this.getDevicesByParams(
@@ -552,8 +554,7 @@
                            .build());
            // 验证授权数量
            validateAuthorization(devicesList.size(), 1);
        }
        catch (Exception e) {
        } catch (Exception e) {
            return Optional.empty();
        }
        // 调用验证方法
@@ -863,9 +864,9 @@
    /**
     * 根据域名分页获取已绑定的设备信息
     *
     * @param page      当前页码
     * @param pageSize  每页显示数量
     * @param domain    域名
     * @param page     当前页码
     * @param pageSize 每页显示数量
     * @param domain   域名
     * @return PaginationData<DeviceDTO> 包含分页信息的设备DTO列表
     */
    @Override
@@ -1186,7 +1187,7 @@
     * 处理获取机场组织信息的请求
     *
     * @param receiver 接收到的消息
     * @param headers 消息头
     * @param headers  消息头
     */
    @ServiceActivator(inputChannel = ChannelName.INBOUND_REQUESTS_AIRPORT_ORGANIZATION_GET, outputChannel =
            ChannelName.OUTBOUND)
@@ -1195,10 +1196,10 @@
                OrganizationGetReceiver.class);
        CommonTopicResponse.CommonTopicResponseBuilder<RequestsReply> builder =
                CommonTopicResponse.<RequestsReply>builder()
                .tid(receiver.getTid())
                .bid(receiver.getBid())
                .method(RequestsMethodEnum.AIRPORT_ORGANIZATION_GET.getMethod())
                .timestamp(System.currentTimeMillis());
                        .tid(receiver.getTid())
                        .bid(receiver.getBid())
                        .method(RequestsMethodEnum.AIRPORT_ORGANIZATION_GET.getMethod())
                        .timestamp(System.currentTimeMillis());
        String topic = headers.get(MqttHeaders.RECEIVED_TOPIC).toString() + TopicConst._REPLY_SUF;
@@ -1219,4 +1220,10 @@
        messageSender.publish(topic, builder.build());
    }
    @DataScopePlus(deptAlias="d")
    @Override
    public List<DeviceEntity> selectList(Wrapper<DeviceEntity> queryWrapper) {
        return mapper.selectList(queryWrapper);
    }
}