Forráskód Böngészése

FEAT: 直播订单新增权限

xdd 2 hete
szülő
commit
3c4263e9b9

+ 80 - 0
fs-admin/src/main/java/com/fs/core/config/LoginContextCallback.java

@@ -0,0 +1,80 @@
+// fs-company模块
+package com.fs.core.config;
+
+import com.fs.common.core.domain.entity.SysUser;
+import com.fs.common.enums.DataScopeEnum;
+import com.fs.common.utils.StringUtils;
+import com.fs.core.security.LoginUser;
+import com.fs.core.security.SecurityUtils;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+import java.util.Set;
+
+/**
+ * 登录上下文回调实现
+ */
+@Component
+public class LoginContextCallback implements com.fs.common.config.LoginContextCallback, ApplicationContextAware {
+
+    private static ApplicationContext applicationContext;
+    /** 所有权限标识 */
+    private static final String ALL_PERMISSION = "*:*:*";
+    @Override
+    public Long getUserId() {
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        return loginUser != null ? loginUser.getUser().getUserId() : null;
+    }
+
+    @Override
+    public Long getCompanyUserId() {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public String getUsername() {
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        return loginUser.getUsername();
+    }
+
+    @Override
+    public String getCompanyUserName() {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public Long getCompanyId() {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public Long getDeptId() {
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        SysUser user = loginUser.getUser();
+        return user.getDeptId();
+    }
+
+
+    @Override
+    public boolean hasPermission(String permission){
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        Set<String> permissions = loginUser.getPermissions();
+        return permissions.contains(ALL_PERMISSION) || permissions.contains(StringUtils.trim(permission));
+    }
+
+
+    @Override
+    public DataScopeEnum getDataScope(){
+        return null;
+    }
+
+
+
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        LoginContextCallback.applicationContext = applicationContext;
+    }
+}

+ 13 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveOrderController.java

@@ -2,6 +2,7 @@ package com.fs.live.controller;
 
 import cn.hutool.core.util.StrUtil;
 import com.fs.common.annotation.Log;
+import com.fs.common.config.LoginContextManager;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
@@ -48,6 +49,7 @@ import com.fs.store.service.IFsExpressService;
 import com.fs.store.service.IFsUserService;
 import com.fs.task.LiveTask;
 import io.swagger.annotations.ApiOperation;
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.http.util.Asserts;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
@@ -364,6 +366,17 @@ public class LiveOrderController extends BaseController
         }
 
         ErpOrderQueryResponse response = erpOrderService.getOrderLive(request);
+
+        if(CollectionUtils.isNotEmpty(response.getOrders())){
+            ErpOrderQuery erpOrderQuery = response.getOrders().get(0);
+            if(!LoginContextManager.hasPermission("live:liveOrder:queryAddress")){
+                erpOrderQuery.setReceiver_address(ParseUtils.parseAddress(erpOrderQuery.getReceiver_address()));
+            }
+            if(!LoginContextManager.hasPermission("live:liveOrder:queryPhone")){
+                erpOrderQuery.setReceiver_mobile(ParseUtils.parsePhone(erpOrderQuery.getReceiver_mobile()));
+                erpOrderQuery.setReceiver_phone(ParseUtils.parsePhone(erpOrderQuery.getReceiver_phone()));
+            }
+        }
         return R.ok().put("data",response);
     }
 

+ 57 - 0
fs-common/src/main/java/com/fs/common/config/LoginContextCallback.java

@@ -0,0 +1,57 @@
+// fs-service模块
+package com.fs.common.config;
+
+
+import com.fs.common.enums.DataScopeEnum;
+
+/**
+ * 登录上下文回调接口
+ */
+public interface LoginContextCallback {
+
+    /**
+     * 获取当前用户ID
+     */
+    Long getUserId();
+
+    /**
+     * 获取companyUserId
+     * 销售端有值
+     */
+    Long getCompanyUserId();
+
+    /**
+     * 获取用户名
+     */
+    String getUsername();
+
+    /**
+     * 获取当前销售用户名
+     * @return String
+     */
+    String getCompanyUserName();
+
+    /**
+     * 获取租户ID
+     */
+    Long getCompanyId();
+
+    /**
+     * 获取部门ID
+     * @return 部门ID
+     */
+    Long getDeptId();
+
+    /**
+     * 获取当前登录用户数据权限
+     * @return DataScopeEnum
+     */
+    DataScopeEnum getDataScope();
+
+    /**
+     * 当前用户是否拥有某个权限
+     * @param permission 权限字符
+     * @return boolean
+     */
+    boolean hasPermission(String permission);
+}

+ 97 - 0
fs-common/src/main/java/com/fs/common/config/LoginContextManager.java

@@ -0,0 +1,97 @@
+// fs-service模块
+package com.fs.common.config;
+
+import com.fs.common.enums.DataScopeEnum;
+
+/**
+ * 登录上下文管理器
+ * 线程安全的上下文管理
+ */
+public class LoginContextManager {
+
+    private static final ThreadLocal<LoginContextCallback> callbackHolder = new ThreadLocal<>();
+
+    /**
+     * 设置上下文回调函数
+     */
+    public static void setContextCallback(LoginContextCallback callback) {
+        callbackHolder.set(callback);
+    }
+
+    /**
+     * 获取当前用户ID
+     */
+    public static Long getCurrentUserId() {
+        LoginContextCallback callback = callbackHolder.get();
+        return callback != null ? callback.getUserId() : null;
+    }
+
+    /**
+     * 获取companyUserId
+     */
+    public static Long getCurrentCompanyUserId() {
+        LoginContextCallback callback = callbackHolder.get();
+        return callback != null ? callback.getCompanyUserId() : null;
+    }
+
+    /**
+     * 获取用户名
+     */
+    public static String getCurrentUsername() {
+        LoginContextCallback callback = callbackHolder.get();
+        return callback != null ? callback.getUsername() : null;
+    }
+
+    /**
+     * 获取租户ID
+     */
+    public static Long getCurrentCompanyId() {
+        LoginContextCallback callback = callbackHolder.get();
+        return callback != null ? callback.getCompanyId() : null;
+    }
+
+    /**
+     * 获取当前部门ID
+     * @return 部门ID
+     */
+    public static Long getCurrentDeptId(){
+        LoginContextCallback callback = callbackHolder.get();
+        return callback != null ? callback.getDeptId() : null;
+    }
+
+    /**
+     * 获取当前用户的数据权限
+     * @return DataScopeEnum
+     */
+    public static DataScopeEnum getDataScope(){
+        LoginContextCallback callback = callbackHolder.get();
+        return callback != null ? callback.getDataScope() : null;
+    }
+
+
+
+    /**
+     * 清理上下文
+     */
+    public static void clearContext() {
+        callbackHolder.remove();
+    }
+
+    /**
+     * 检查是否有有效的上下文
+     */
+    public static boolean hasContext() {
+        LoginContextCallback callback = callbackHolder.get();
+        return callback != null && callback.getUserId() != null;
+    }
+
+    /**
+     * 当前用户是否有指定资源的权限
+     * @param permission 权限支付
+     * @return boolean
+     */
+    public static boolean hasPermission(String permission) {
+        LoginContextCallback callback = callbackHolder.get();
+        return callback != null && callback.hasPermission(permission);
+    }
+}

+ 174 - 0
fs-common/src/main/java/com/fs/common/enums/DataScopeEnum.java

@@ -0,0 +1,174 @@
+package com.fs.common.enums;
+
+import lombok.Getter;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * 数据权限范围枚举
+ * 定义系统中不同层级的数据访问权限
+ *
+ * @author System
+ * @date 2024年
+ */
+@Getter
+public enum DataScopeEnum {
+
+    /**
+     * 全部数据权限 - 最高权限级别,可以访问所有数据
+     */
+    ALL("1", "全部数据权限"),
+
+    /**
+     * 自定义数据权限 - 根据用户自定义的权限规则访问数据
+     */
+    CUSTOM("2", "自定数据权限"),
+
+    /**
+     * 本部门数据权限 - 只能访问用户所属部门的数据
+     */
+    DEPARTMENT("3", "本部门数据权限"),
+
+    /**
+     * 本部门及以下数据权限 - 可以访问用户所属部门及其下级部门的数据
+     */
+    DEPARTMENT_AND_BELOW("4", "本部门及以下数据权限"),
+    /**
+     * 仅本人数据权限
+     */
+    SELF_ONLY("5", "仅本人数据权限");
+
+    /**
+     * 权限类型代码
+     * -- GETTER --
+     *  获取权限代码
+     *
+     * @return 权限代码
+
+     */
+    private final String code;
+
+    /**
+     * 权限描述信息
+     * -- GETTER --
+     *  获取权限描述
+     *
+     * @return 权限描述
+
+     */
+    private final String description;
+
+    /**
+     * 代码到枚举值的映射缓存,用于快速查找
+     */
+    private static final Map<String, DataScopeEnum> CODE_MAP = Arrays.stream(values())
+            .collect(Collectors.toMap(DataScopeEnum::getCode, Function.identity()));
+
+    /**
+     * 构造函数
+     *
+     * @param code 权限代码
+     * @param description 权限描述
+     */
+    DataScopeEnum(String code, String description) {
+        this.code = code;
+        this.description = description;
+    }
+
+    /**
+     * 根据代码获取对应的枚举值
+     *
+     * @param code 权限代码
+     * @return 对应的枚举值,如果不存在则返回null
+     */
+    public static DataScopeEnum getByCode(String code) {
+        return CODE_MAP.get(code);
+    }
+
+    /**
+     * 根据代码获取对应的枚举值,如果不存在则抛出异常
+     *
+     * @param code 权限代码
+     * @return 对应的枚举值
+     * @throws IllegalArgumentException 如果代码对应的枚举值不存在
+     */
+    public static DataScopeEnum getByCodeOrThrow(String code) {
+        DataScopeEnum enumValue = CODE_MAP.get(code);
+        if (enumValue == null) {
+            throw new IllegalArgumentException("无效的数据权限代码: " + code);
+        }
+        return enumValue;
+    }
+
+    /**
+     * 验证代码是否有效
+     *
+     * @param code 待验证的权限代码
+     * @return 如果代码有效返回true,否则返回false
+     */
+    public static boolean isValidCode(String code) {
+        return CODE_MAP.containsKey(code);
+    }
+
+    /**
+     * 获取所有有效的权限代码数组
+     *
+     * @return 权限代码数组
+     */
+    public static String[] getAllCodes() {
+        return CODE_MAP.keySet().toArray(new String[0]);
+    }
+
+    /**
+     * 检查当前权限是否包含另一个权限
+     * 权限层级关系:ALL > DEPARTMENT_AND_BELOW > DEPARTMENT > CUSTOM
+     *
+     * @param other 另一个权限
+     * @return 如果当前权限包含或等于另一个权限返回true
+     */
+    public boolean contains(DataScopeEnum other) {
+        if (this == ALL) {
+            return true; // 全部权限包含所有权限
+        }
+        if (this == DEPARTMENT_AND_BELOW) {
+            return other == DEPARTMENT_AND_BELOW || other == DEPARTMENT || other == CUSTOM;
+        }
+        if (this == DEPARTMENT) {
+            return other == DEPARTMENT || other == CUSTOM;
+        }
+        return this == other; // CUSTOM 只包含自己
+    }
+
+    /**
+     * 获取权限的层级值(数值越小权限越大)
+     *
+     * @return 层级值
+     */
+    public int getLevel() {
+        switch (this) {
+            case ALL: return 1;
+            case DEPARTMENT_AND_BELOW: return 2;
+            case DEPARTMENT: return 3;
+            case CUSTOM: return 4;
+            default: return 5;
+        }
+    }
+
+    /**
+     * 比较两个权限的层级
+     *
+     * @param other 另一个权限
+     * @return 如果当前权限层级更高返回正数,相同返回0,更低返回负数
+     */
+    public int compareLevel(DataScopeEnum other) {
+        return Integer.compare(other.getLevel(), this.getLevel());
+    }
+
+    @Override
+    public String toString() {
+        return code + ":" + description;
+    }
+}

+ 14 - 2
fs-service-system/src/main/java/com/fs/live/service/impl/LiveOrderServiceImpl.java

@@ -24,6 +24,7 @@ import com.alibaba.fastjson.JSON;
 
 import com.alibaba.fastjson.JSONObject;
 import com.fs.common.config.FSSysConfig;
+import com.fs.common.config.LoginContextManager;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.common.event.TemplateBean;
@@ -215,6 +216,9 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
     @Autowired
     private LiveAfterSalesMapper liveAfterSalesMapper;
 
+    @Autowired
+    private ILiveOrderService liveOrderService;
+
 
     public LiveOrderServiceImpl(RedisCache redisCache) {
         this.redisCache = redisCache;
@@ -683,11 +687,19 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
             liveOrder.setDeliveryStatus(null);
             liveOrder.setDeliveryType(null);
         }
+
+        // 判断当前用户是否有指定数据权限
+        if(!LoginContextManager.hasPermission("live:liveOrder:queryAddress")){
+            liveOrder.setUserAddress(ParseUtils.parseAddress(liveOrder.getUserAddress()));
+        }
+        if(!LoginContextManager.hasPermission("live:liveOrder:queryPhone")){
+            liveOrder.setUserPhone(ParseUtils.parsePhone(liveOrder.getUserPhone()));
+        }
+
         return liveOrder;
     }
 
-    @Autowired
-    private ILiveOrderService liveOrderService;
+
     @Override
     @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
     public void editLiveOrderDeliveryId(FsStoreDelivers deliveryDTO) {