From ddf364ed076204206fbba47f2947b30cbbd21ecb Mon Sep 17 00:00:00 2001
From: zhaowenyu <35589726@qq.com>
Date: Fri, 31 Oct 2025 16:16:11 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev' into dev
---
ard-admin/src/main/java/com/ard/web/controller/sample/DeviceController.java | 50 +++++++++
ard-sample/src/main/java/com/ard/sample/manage/service/IDeviceService.java | 5 +
ard-framework/src/main/java/com/ard/framework/aspectj/DataScopePlusAspect.java | 136 +++++++++++++++++++++++++++
ard-sample/src/main/java/com/ard/sample/manage/service/impl/DeviceServiceImpl.java | 33 ++++--
ard-common/src/main/java/com/ard/common/annotation/DataScopePlus.java | 29 +++++
5 files changed, 239 insertions(+), 14 deletions(-)
diff --git a/ard-admin/src/main/java/com/ard/web/controller/sample/DeviceController.java b/ard-admin/src/main/java/com/ard/web/controller/sample/DeviceController.java
index e11e1e5..0b561b6 100644
--- a/ard-admin/src/main/java/com/ard/web/controller/sample/DeviceController.java
+++ b/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();
+ }
}
\ No newline at end of file
diff --git a/ard-common/src/main/java/com/ard/common/annotation/DataScopePlus.java b/ard-common/src/main/java/com/ard/common/annotation/DataScopePlus.java
new file mode 100644
index 0000000..1f9e49c
--- /dev/null
+++ b/ard-common/src/main/java/com/ard/common/annotation/DataScopePlus.java
@@ -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 "";
+}
diff --git a/ard-framework/src/main/java/com/ard/framework/aspectj/DataScopePlusAspect.java b/ard-framework/src/main/java/com/ard/framework/aspectj/DataScopePlusAspect.java
new file mode 100644
index 0000000..60ad5bb
--- /dev/null
+++ b/ard-framework/src/main/java/com/ard/framework/aspectj/DataScopePlusAspect.java
@@ -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;
+ }
+}
diff --git a/ard-sample/src/main/java/com/ard/sample/manage/service/IDeviceService.java b/ard-sample/src/main/java/com/ard/sample/manage/service/IDeviceService.java
index dd5f82a..42d8f10 100644
--- a/ard-sample/src/main/java/com/ard/sample/manage/service/IDeviceService.java
+++ b/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);
}
\ No newline at end of file
diff --git a/ard-sample/src/main/java/com/ard/sample/manage/service/impl/DeviceServiceImpl.java b/ard-sample/src/main/java/com/ard/sample/manage/service/impl/DeviceServiceImpl.java
index 7466075..fc5dd06 100644
--- a/ard-sample/src/main/java/com/ard/sample/manage/service/impl/DeviceServiceImpl.java
+++ b/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);
+ }
}
\ No newline at end of file
--
Gitblit v1.9.3