Переглянути джерело

add 增加第三方应用api接入管理

A17404李放 3 роки тому
батько
коміт
99f9766525

+ 69 - 0
nb-common/src/main/java/com/nb/common/apply/ApplyManager.java

@@ -0,0 +1,69 @@
+package com.nb.common.apply;
+
+import java.util.Collection;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName ApplyManagerc.java
+ * @Description
+ * @see  com.nb.system.config.DefaultApplyManager
+ * @createTime 2022年07月27日 10:46:00
+ */
+public interface ApplyManager {
+    /**
+     * 描述: 产生appKey
+     * @author lifang
+     * @date 2022/7/27 10:52
+     * @param timestamp
+     * @return String
+     */
+    String generateAppKey(Long timestamp);
+
+    /**
+     * 描述: 根据appKey产生appSecret
+     * @author lifang
+     * @date 2022/7/27 10:53
+     * @param appKey
+     * @return String
+     */
+    String generateAppSecret(String appKey);
+
+    /**
+     * 描述: 根据appKey获取appSecret
+     * @author lifang
+     * @date 2022/7/27 10:53
+     * @param appKey
+     * @return String
+     */
+    String getAppSecret(String appKey);
+
+    /**
+     * 描述: 缓存appKey和appSecret
+     * @author lifang
+     * @date 2022/7/27 10:54
+     * @param appKey
+     * @param appSecret
+     * @return void
+     */
+    void setApply(String appKey,String appSecret,String tenantId);
+
+    /**
+     * 描述: 获取相应的医院id
+     * @author lifang
+     * @date 2022/7/27 14:37
+     * @param appKey
+     * @return String
+     */
+    String getTenantId(String appKey);
+
+
+    /**
+     * 描述: 获取相应的全现集合
+     * @author lifang
+     * @date 2022/7/27 14:38
+     * @param appKey
+     * @return Collection<String>
+     */
+    Collection<String> getPermission(String appKey);
+}

+ 6 - 3
nb-common/src/main/java/com/nb/common/bo/LoginUser.java

@@ -5,8 +5,6 @@ import lombok.Data;
 
 import java.io.Serializable;
 import java.util.Date;
-import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 /**
@@ -40,7 +38,12 @@ public class LoginUser implements Serializable {
     private SysUserBO sysUser;
 
     /**
-     * 用户名
+     * 系统用户
+     */
+    private SysApplyBO sysApply;
+
+    /**
+     * 用户名 或者 appkey
      */
     private String username;
 

+ 21 - 0
nb-common/src/main/java/com/nb/common/bo/SysApplyBO.java

@@ -0,0 +1,21 @@
+package com.nb.common.bo;
+
+import lombok.Data;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName SysApplyBO.java
+ * @Description TODO
+ * @createTime 2022年07月27日 11:53:00
+ */
+@Data
+public class SysApplyBO {
+
+    private String appKey;
+
+    /**
+     * (医院)租户id
+     **/
+    private String tenantId;
+}

+ 1 - 2
nb-common/src/main/java/com/nb/common/enums/GrantTypeEnum.java

@@ -26,7 +26,7 @@ public enum GrantTypeEnum {
     /**
      * appkey、appSecret模式
      */
-    APPKEY_APPSECRET("3", "appkey,appSecret模式"),;
+    APPKEY_APPSECRET("3", "第三方应用登录"),;
 
     private String code;
     private String desc;
@@ -35,5 +35,4 @@ public enum GrantTypeEnum {
     public static Boolean contains(String code) {
         return Arrays.stream(GrantTypeEnum.values()).anyMatch(temp -> temp.getCode().equals(code));
     }
-
 }

+ 12 - 0
nb-common/src/main/java/com/nb/common/exception/apply/ApplyException.java

@@ -0,0 +1,12 @@
+package com.nb.common.exception.apply;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName ApplyException.java
+ * @Description 第三方应用错误
+ * @createTime 2022年07月27日 14:23:00
+ */
+public class ApplyException extends RuntimeException {
+
+}

+ 16 - 0
nb-common/src/main/java/com/nb/common/exception/apply/ApplyTokenParamException.java

@@ -0,0 +1,16 @@
+package com.nb.common.exception.apply;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName ApplyTokenException.java
+ * @Description 换取token参数错误
+ * @createTime 2022年07月27日 14:25:00
+ */
+public class ApplyTokenParamException extends ApplyException {
+    private String msg;
+
+    public ApplyTokenParamException(String msg) {
+        this.msg = msg;
+    }
+}

+ 15 - 1
nb-common/src/main/java/com/nb/common/util/SecurityUtil.java

@@ -9,6 +9,7 @@ import com.nb.common.Constants;
 import com.nb.common.bo.LoginUser;
 import com.nb.common.bo.SysRoleBO;
 import com.nb.common.bo.SysUserBO;
+import com.nb.common.enums.GrantTypeEnum;
 
 import java.util.List;
 import java.util.Objects;
@@ -34,6 +35,7 @@ public class SecurityUtil {
         return getLoginUser().getSysUser();
     }
 
+
     /**
      * 获取用户
      **/
@@ -46,7 +48,15 @@ public class SecurityUtil {
     }
 
     public static boolean isSys(){
-        return Boolean.TRUE.equals(getLoginUser().getIsSys());
+        LoginUser loginUser = getLoginUser();
+        if(loginUser==null){
+            return false;
+        }
+        String grantType = loginUser.getGrantType();
+        if (GrantTypeEnum.APPKEY_APPSECRET.getCode().equalsIgnoreCase(grantType)) {
+            return false;
+        }
+        return Boolean.TRUE.equals(loginUser.getIsSys());
     }
 
     public static String getTenantId(){
@@ -56,6 +66,10 @@ public class SecurityUtil {
      * 是否是超级管理员
      **/
     public static Boolean isSuperAdmin() {
+        String grantType = getLoginUser().getGrantType();
+        if (GrantTypeEnum.APPKEY_APPSECRET.getCode().equalsIgnoreCase(grantType)) {
+            return false;
+        }
         List<SysRoleBO> roles = getSysUser().getRoles();
         if(CollUtil.isEmpty(roles)){
             return false;

+ 175 - 107
nb-framework/src/main/java/com/nb/framework/web/service/impl/UserServiceImpl.java

@@ -5,23 +5,29 @@ import cn.dev33.satoken.stp.StpUtil;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.StrUtil;
+import cn.hutool.crypto.digest.DigestUtil;
 import cn.hutool.http.useragent.UserAgent;
 import cn.hutool.http.useragent.UserAgentUtil;
+import cn.hutool.json.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.nb.common.Constants;
 import com.nb.common.MenuConstants;
+import com.nb.common.apply.ApplyManager;
 import com.nb.common.bo.LoginUser;
+import com.nb.common.bo.SysApplyBO;
 import com.nb.common.bo.SysRoleBO;
 import com.nb.common.bo.SysUserBO;
 import com.nb.common.dto.LoginDTO;
 import com.nb.common.enums.*;
 import com.nb.common.exception.CustomException;
+import com.nb.common.exception.apply.ApplyTokenParamException;
 import com.nb.common.util.AddressUtil;
 import com.nb.common.util.IpUtil;
 import com.nb.common.util.SecurityUtil;
 import com.nb.framework.web.service.IUserService;
 import com.nb.system.common.vo.*;
+import com.nb.system.entity.SysApply;
 import com.nb.system.entity.SysMenu;
 import com.nb.system.entity.SysRole;
 import com.nb.system.entity.SysUser;
@@ -32,7 +38,9 @@ import com.nb.system.service.ISysUserService;
 import com.nb.system.utils.CaptchaTool;
 import com.google.common.collect.Sets;
 import com.nb.system.utils.TenantUtil;
+import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.stereotype.Service;
 
@@ -48,23 +56,21 @@ import java.util.stream.Collectors;
  */
 @Slf4j
 @Service
+@AllArgsConstructor
 @EnableConfigurationProperties(CaptchaProperties.class)
 public class UserServiceImpl implements IUserService {
 
-    @Resource
-    private ISysMenuService sysMenuService;
+    private final ISysMenuService sysMenuService;
 
-    @Resource
-    private CaptchaTool captchaTool;
+    private final CaptchaTool captchaTool;
 
-    @Resource
-    private CaptchaProperties captchaProperties;
+    private final CaptchaProperties captchaProperties;
 
-    @Resource
-    private ISysUserService sysUserService;
+    private final ISysUserService sysUserService;
 
-    @Resource
-    private ISysRoleService sysRoleService;
+    private final ISysRoleService sysRoleService;
+
+    private final ApplyManager applyManager;
 
     @Override
     public String login(LoginDTO req) {
@@ -74,103 +80,10 @@ public class UserServiceImpl implements IUserService {
         if (!GrantTypeEnum.contains(req.getGrantType())) {
             throw new CustomException("授权类型暂不支持");
         }
-        SysUser sysUser = null;
-        if (req.getGrantType().equals(GrantTypeEnum.USERNAME_PASSWORD.getCode())) {
-            if (StrUtil.isBlank(req.getUsername())) {
-                throw new CustomException("用户名不能为空");
-            }
-            if (StrUtil.isBlank(req.getPassword())) {
-                throw new CustomException("密码不能为空");
-            }
-            if(captchaProperties.isEnable()){
-                HttpServletRequest request = SpringMVCUtil.getRequest();
-                String requestFrom = request.getHeader("RequestFrom");
-                //来自app的请求不需要验证码
-//                if(!"TuoRenApp".equals(requestFrom)){
-//                    captchaTool.ver(req.getCodeKey(),req.getCode());
-//                }
-            }
-            sysUser = sysUserService.getOne(Wrappers.lambdaQuery(SysUser.class).eq(SysUser::getAccount, req.getUsername()));
-            if (Objects.isNull(sysUser)) {
-                log.info("登录用户:{}不存在", req.getUsername());
-                throw new CustomException("登录用户不存在");
-            }
-            if (!SecurityUtil.matchesPassword(req.getPassword(), sysUser.getPassword())) {
-                throw new CustomException("账号或密码不正确");
-            }
-            if (sysUser.getDelFlag().equals(DelFlagEnum.YES.getCode())) {
-                log.info("登录用户:{}已被删除", req.getUsername());
-                throw new CustomException("对不起,您的账号已被删除");
-            }
-            if (sysUser.getStatus().equals(StatusEnum.NO.getCode())) {
-                log.info("登录用户:{}已被停用", req.getUsername());
-                throw new CustomException("对不起,您的账号已被停用");
-            }
-        }
-        if (req.getGrantType().equals(GrantTypeEnum.MOBILE_CODE.getCode())) {
-            if (StrUtil.isBlank(req.getMobile())) {
-                throw new CustomException("手机号不能为空");
-            }
-            if (StrUtil.isBlank(req.getCode())) {
-                throw new CustomException("验证码不能为空");
-            }
-            // TODO,短信验证码校验,自行实现
-            if (!Objects.equals(req.getCode(), Constants.DEFAULT_SMS_CODE)) {
-                throw new CustomException("账号或密码不正确");
-            }
-            sysUser = sysUserService.getOne(Wrappers.lambdaQuery(SysUser.class).eq(SysUser::getPhone, req.getMobile()));
-            if (Objects.isNull(sysUser)) {
-                log.info("登录用户:{}不存在", req.getUsername());
-                throw new CustomException("登录用户不存在");
-            }
-            if (sysUser.getDelFlag().equals(DelFlagEnum.YES.getCode())) {
-                log.info("登录用户:{}已被删除", req.getUsername());
-                throw new CustomException("对不起,您的账号已被删除");
-            }
-            if (sysUser.getStatus().equals(StatusEnum.NO.getCode())) {
-                log.info("登录用户:{}已被停用", req.getUsername());
-                throw new CustomException("对不起,您的账号已被停用");
-            }
-        }
-        log.info("登录用户:{}", req.getUsername());
-        SysUserBO sysUserBO = BeanUtil.copyProperties(sysUser, SysUserBO.class);
-        // 查询角色列表
-        List<SysRole> sysRoleList = sysRoleService.listSysRoleByUserId(sysUser.getId());
-        // 设置角色列表
-        sysUserBO.setRoles(sysRoleList.stream().map(item -> BeanUtil.copyProperties(item, SysRoleBO.class)).collect(Collectors.toList()));
-        // 查询权限标识
-        Set<String> permissions = Sets.newHashSet();
-        if (CollUtil.isNotEmpty(sysRoleList)&&
-                sysRoleList.stream().anyMatch(sysRole -> "admin".equalsIgnoreCase(sysRole.getRoleCode()))) {
-            permissions.add(Constants.ALL_PERMISSION);
-        } else {
-            permissions = sysMenuService.getPermissionsByUserId(sysUser.getId());
-        }
-        // 登录
-        StpUtil.login(sysUser.getId());
-        LoginUser loginUser = new LoginUser();
-        loginUser.setToken(StpUtil.getTokenValue());
-        loginUser.setUserPlatform(UserPlatformEnum.WEB.getCode());
-        loginUser.setGrantType(req.getGrantType());
-        loginUser.setSysUser(sysUserBO);
-        loginUser.setIsSys(sysUser.getIsSys());
-        if (req.getGrantType().equals(GrantTypeEnum.USERNAME_PASSWORD.getCode())) {
-            loginUser.setUsername(req.getUsername());
-        }
-        if (req.getGrantType().equals(GrantTypeEnum.MOBILE_CODE.getCode())) {
-            loginUser.setUsername(req.getMobile());
-        }
-        loginUser.setLoginTime(new Date());
-        HttpServletRequest request = SpringMVCUtil.getRequest();
-        UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));
-        String ipAddress = IpUtil.getClientIp(request);
-        loginUser.setIpAddress(ipAddress);
-        loginUser.setLoginLocation(AddressUtil.getRealAddressByIp(ipAddress));
-        loginUser.setBrowser(userAgent.getBrowser().getName());
-        loginUser.setOs(userAgent.getOs().getName());
-        loginUser.setPermissions(permissions);
-        // 设置用户信息
-        StpUtil.getTokenSession().set(Constants.LOGIN_USER_KEY, loginUser);
+        //用户登录
+        userLogin(req);
+        //第三方应用登录
+        applyLogin(req);
         return StpUtil.getTokenValue();
     }
 
@@ -291,4 +204,159 @@ public class UserServiceImpl implements IUserService {
         return node;
     }
 
+
+
+    private void userLogin(LoginDTO req){
+        SysUser sysUser = null;
+        if (req.getGrantType().equals(GrantTypeEnum.USERNAME_PASSWORD.getCode())) {
+            if (StrUtil.isBlank(req.getUsername())) {
+                throw new CustomException("用户名不能为空");
+            }
+            if (StrUtil.isBlank(req.getPassword())) {
+                throw new CustomException("密码不能为空");
+            }
+            if(captchaProperties.isEnable()){
+                HttpServletRequest request = SpringMVCUtil.getRequest();
+                String requestFrom = request.getHeader("RequestFrom");
+                //来自app的请求不需要验证码
+                if(!"TuoRenApp".equals(requestFrom)){
+                    captchaTool.ver(req.getCodeKey(),req.getCode());
+                }
+            }
+            sysUser = sysUserService.getOne(Wrappers.lambdaQuery(SysUser.class).eq(SysUser::getAccount, req.getUsername()));
+            if (Objects.isNull(sysUser)) {
+                log.info("登录用户:{}不存在", req.getUsername());
+                throw new CustomException("登录用户不存在");
+            }
+            if (!SecurityUtil.matchesPassword(req.getPassword(), sysUser.getPassword())) {
+                throw new CustomException("账号或密码不正确");
+            }
+            if (sysUser.getDelFlag().equals(DelFlagEnum.YES.getCode())) {
+                log.info("登录用户:{}已被删除", req.getUsername());
+                throw new CustomException("对不起,您的账号已被删除");
+            }
+            if (sysUser.getStatus().equals(StatusEnum.NO.getCode())) {
+                log.info("登录用户:{}已被停用", req.getUsername());
+                throw new CustomException("对不起,您的账号已被停用");
+            }
+        }else if (req.getGrantType().equals(GrantTypeEnum.MOBILE_CODE.getCode())) {
+            if (StrUtil.isBlank(req.getMobile())) {
+                throw new CustomException("手机号不能为空");
+            }
+            if (StrUtil.isBlank(req.getCode())) {
+                throw new CustomException("验证码不能为空");
+            }
+            // TODO,短信验证码校验,自行实现
+            if (!Objects.equals(req.getCode(), Constants.DEFAULT_SMS_CODE)) {
+                throw new CustomException("账号或密码不正确");
+            }
+            sysUser = sysUserService.getOne(Wrappers.lambdaQuery(SysUser.class).eq(SysUser::getPhone, req.getMobile()));
+            if (Objects.isNull(sysUser)) {
+                log.info("登录用户:{}不存在", req.getUsername());
+                throw new CustomException("登录用户不存在");
+            }
+            if (sysUser.getDelFlag().equals(DelFlagEnum.YES.getCode())) {
+                log.info("登录用户:{}已被删除", req.getUsername());
+                throw new CustomException("对不起,您的账号已被删除");
+            }
+            if (sysUser.getStatus().equals(StatusEnum.NO.getCode())) {
+                log.info("登录用户:{}已被停用", req.getUsername());
+                throw new CustomException("对不起,您的账号已被停用");
+            }
+        }else {
+            return;
+        }
+        log.info("登录用户:{}", req.getUsername());
+        SysUserBO sysUserBO = BeanUtil.copyProperties(sysUser, SysUserBO.class);
+        // 查询角色列表
+        List<SysRole> sysRoleList = sysRoleService.listSysRoleByUserId(sysUser.getId());
+        // 设置角色列表
+        sysUserBO.setRoles(sysRoleList.stream().map(item -> BeanUtil.copyProperties(item, SysRoleBO.class)).collect(Collectors.toList()));
+        // 查询权限标识
+        Set<String> permissions = Sets.newHashSet();
+        if (CollUtil.isNotEmpty(sysRoleList)&&
+                sysRoleList.stream().anyMatch(sysRole -> "admin".equalsIgnoreCase(sysRole.getRoleCode()))) {
+            permissions.add(Constants.ALL_PERMISSION);
+        } else {
+            permissions = sysMenuService.getPermissionsByUserId(sysUser.getId());
+        }
+        // 登录
+        StpUtil.login(sysUser.getId());
+        LoginUser loginUser = new LoginUser();
+        loginUser.setToken(StpUtil.getTokenValue());
+        loginUser.setUserPlatform(UserPlatformEnum.WEB.getCode());
+        loginUser.setGrantType(req.getGrantType());
+        loginUser.setSysUser(sysUserBO);
+        loginUser.setIsSys(sysUser.getIsSys());
+        if (req.getGrantType().equals(GrantTypeEnum.USERNAME_PASSWORD.getCode())) {
+            loginUser.setUsername(req.getUsername());
+        }
+        if (req.getGrantType().equals(GrantTypeEnum.MOBILE_CODE.getCode())) {
+            loginUser.setUsername(req.getMobile());
+        }
+        loginUser.setLoginTime(new Date());
+        HttpServletRequest request = SpringMVCUtil.getRequest();
+        UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));
+        String ipAddress = IpUtil.getClientIp(request);
+        loginUser.setIpAddress(ipAddress);
+        loginUser.setLoginLocation(AddressUtil.getRealAddressByIp(ipAddress));
+        loginUser.setBrowser(userAgent.getBrowser().getName());
+        loginUser.setOs(userAgent.getOs().getName());
+        loginUser.setPermissions(permissions);
+        // 设置用户信息
+        StpUtil.getTokenSession().set(Constants.LOGIN_USER_KEY, loginUser);
+    }
+
+    private void applyLogin(LoginDTO req){
+        if (req.getGrantType().equals(GrantTypeEnum.APPKEY_APPSECRET.getCode())){
+            if (StrUtil.isBlank(req.getAppKey())) {
+                throw new ApplyTokenParamException("appKey不能为空");
+            }
+            if (StrUtil.isBlank(req.getTimestamp())) {
+                throw new ApplyTokenParamException("timestamp不能为空");
+            }
+            if (StrUtil.isBlank(req.getSign())) {
+                throw new ApplyTokenParamException("sign不能为空");
+            }
+            String appKey = req.getAppKey();
+            String appSecret = applyManager.getAppSecret(appKey);
+            //验证签名
+            if (signCorrect(req.getSign(), req.getTimestamp(), req.getAppKey(), appSecret)) {
+                LoginUser loginUser = new LoginUser();
+                SysApplyBO sysApply = new SysApplyBO();
+                sysApply.setAppKey(appKey);
+                sysApply.setTenantId(applyManager.getTenantId(appKey));
+                loginUser.setToken(StpUtil.getTokenValue());
+                loginUser.setUserPlatform(UserPlatformEnum.WEB.getCode());
+                loginUser.setGrantType(req.getGrantType());
+                loginUser.setSysApply(sysApply);
+                loginUser.setIsSys(false);
+                loginUser.setUsername(req.getAppKey());
+                loginUser.setLoginTime(new Date());
+                HttpServletRequest request = SpringMVCUtil.getRequest();
+                UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));
+                String ipAddress = IpUtil.getClientIp(request);
+                loginUser.setIpAddress(ipAddress);
+                loginUser.setLoginLocation(AddressUtil.getRealAddressByIp(ipAddress));
+                loginUser.setBrowser(userAgent.getBrowser().getName());
+                loginUser.setOs(userAgent.getOs().getName());
+                loginUser.setPermissions(new HashSet<>(applyManager.getPermission(appKey)));
+                // 设置用户信息
+                StpUtil.getTokenSession().set(Constants.LOGIN_USER_KEY, loginUser);
+            }else {
+                throw new ApplyTokenParamException("签名错误");
+            }
+        }else {
+            return;
+        }
+    }
+
+    private boolean signCorrect(String sign,String timestamp,String appKey,String appSecret){
+        JSONObject jsonObject = new JSONObject(true);
+        jsonObject.putOpt("appKey",appKey)
+                .putOpt("appSecret",appSecret)
+                .putOpt("timestamp",timestamp);
+        return DigestUtil.md5Hex(jsonObject.toString()).equalsIgnoreCase(sign);
+    }
+
 }

+ 2 - 2
nb-system/src/main/java/com/nb/aliyun/utils/DeviceAlarmUtils.java

@@ -31,9 +31,9 @@ public class DeviceAlarmUtils {
         }else if (i == 6){
             // 输液结束
             return DeviceAlarmEnum.Finished;
-        }else if (i == 7){
+//        }else if (i == 7){
             // 电机失控
-            return DeviceAlarmEnum.OutOfControl;
+//            return DeviceAlarmEnum.OutOfControl;
         }else if (i == 8){
             // 机械故障
             return DeviceAlarmEnum.Machine;

+ 1 - 1
nb-system/src/main/java/com/nb/bus/enums/DeviceAlarmEnum.java

@@ -30,7 +30,7 @@ public enum DeviceAlarmEnum  implements IEnum<Integer> {
     Limit(5,"极限报警"),
     Finished(6,"输液结束"),
     LowBattery(7,"电量耗尽报警"),
-    OutOfControl(8,"电机失控报警"),
+//    OutOfControl(8,"电机失控报警"),
     Machine(9,"机械故障"),;
 
 

+ 7 - 7
nb-system/src/main/java/com/nb/bus/stats/analyse/AlarmStatsAnalyse.java

@@ -135,8 +135,8 @@ public class AlarmStatsAnalyse implements CommonStats<CombineAlarmResult> {
                     .add(computeRatio(BigDecimal.valueOf(totalResult.getLimit().getValue()),total));
             lineContentMap.computeIfAbsent("未装药盒率",k->new LineResult.LineContent<>(DeviceAlarmEnum.NotBox.getText())).getValue()
                     .add(computeRatio(BigDecimal.valueOf(totalResult.getNoBox().getValue()),total));
-            lineContentMap.computeIfAbsent("电机失控率",k->new LineResult.LineContent<>(DeviceAlarmEnum.OutOfControl.getText())).getValue()
-                    .add(computeRatio(BigDecimal.valueOf(totalResult.getOutOfControl().getValue()),total));
+//            lineContentMap.computeIfAbsent("电机失控率",k->new LineResult.LineContent<>(DeviceAlarmEnum.OutOfControl.getText())).getValue()
+//                    .add(computeRatio(BigDecimal.valueOf(totalResult.getOutOfControl().getValue()),total));
             lineContentMap.computeIfAbsent("镇痛不足率",k->new LineResult.LineContent<>("镇痛不足")).getValue()
                     .add(computeRatio(BigDecimal.valueOf(totalResult.getAnalgesicPoor().getValue()),total));
             lineContentMap.computeIfAbsent("不在服务区率",k->new LineResult.LineContent<>("不在服务区")).getValue()
@@ -191,7 +191,7 @@ public class AlarmStatsAnalyse implements CommonStats<CombineAlarmResult> {
             lineContentMap.computeIfAbsent(DeviceAlarmEnum.Jam.getText(),k->new LineResult.LineContent<>(DeviceAlarmEnum.Jam.getText())).getValue().add(totalResult.getJam().getValue());
             lineContentMap.computeIfAbsent(DeviceAlarmEnum.Limit.getText(),k->new LineResult.LineContent<>(DeviceAlarmEnum.Limit.getText())).getValue().add(totalResult.getLimit().getValue());
             lineContentMap.computeIfAbsent(DeviceAlarmEnum.NotBox.getText(),k->new LineResult.LineContent<>(DeviceAlarmEnum.NotBox.getText())).getValue().add(totalResult.getNoBox().getValue());
-            lineContentMap.computeIfAbsent(DeviceAlarmEnum.OutOfControl.getText(),k->new LineResult.LineContent<>(DeviceAlarmEnum.OutOfControl.getText())).getValue().add(totalResult.getOutOfControl().getValue());
+//            lineContentMap.computeIfAbsent(DeviceAlarmEnum.OutOfControl.getText(),k->new LineResult.LineContent<>(DeviceAlarmEnum.OutOfControl.getText())).getValue().add(totalResult.getOutOfControl().getValue());
             lineContentMap.computeIfAbsent("镇痛不足",k->new LineResult.LineContent<>("镇痛不足")).getValue().add(totalResult.getAnalgesicPoor().getValue());
             lineContentMap.computeIfAbsent("不在服务区",k->new LineResult.LineContent<>("不在服务区")).getValue().add(totalResult.getNoSignal().getValue());
             lineContentMap.computeIfAbsent(DeviceAlarmEnum.Machine.getText(),k->new LineResult.LineContent<>(DeviceAlarmEnum.Machine.getText())).getValue().add(totalResult.getMachine().getValue());
@@ -230,7 +230,7 @@ public class AlarmStatsAnalyse implements CommonStats<CombineAlarmResult> {
                 DeviceAlarmEnum.Jam.getText(),
                 DeviceAlarmEnum.Limit.getText(),
                 DeviceAlarmEnum.NotBox.getText(),
-                DeviceAlarmEnum.OutOfControl.getText(),
+//                DeviceAlarmEnum.OutOfControl.getText(),
                 "镇痛不足",
                 "不在服务区",
                 DeviceAlarmEnum.Machine.getText(),
@@ -276,7 +276,7 @@ public class AlarmStatsAnalyse implements CommonStats<CombineAlarmResult> {
             contentValues.put( DeviceAlarmEnum.Jam.getText(),totalResult.getJam().getValue());
             contentValues.put( DeviceAlarmEnum.Limit.getText(),totalResult.getLimit().getValue());
             contentValues.put(DeviceAlarmEnum.NotBox.getText(),totalResult.getNoBox().getValue());
-            contentValues.put(DeviceAlarmEnum.OutOfControl.getText(),totalResult.getOutOfControl().getValue());
+//            contentValues.put(DeviceAlarmEnum.OutOfControl.getText(),totalResult.getOutOfControl().getValue());
             contentValues.put("镇痛不足",totalResult.getAnalgesicPoor().getValue());
             contentValues.put("不在服务区",totalResult.getNoSignal().getValue());
             contentValues.put(DeviceAlarmEnum.Machine.getText(),totalResult.getMachine().getValue());
@@ -287,7 +287,7 @@ public class AlarmStatsAnalyse implements CommonStats<CombineAlarmResult> {
             contentValues.put(DeviceAlarmEnum.Jam.getText()+"比率",computeRatio(BigDecimal.valueOf(totalResult.getJam().getValue()),total));
             contentValues.put(DeviceAlarmEnum.Limit.getText()+"比率",computeRatio(BigDecimal.valueOf(totalResult.getLimit().getValue()),total));
             contentValues.put(DeviceAlarmEnum.NotBox.getText()+"比率",computeRatio(BigDecimal.valueOf(totalResult.getNoBox().getValue()),total));
-            contentValues.put(DeviceAlarmEnum.OutOfControl.getText()+"比率",computeRatio(BigDecimal.valueOf(totalResult.getOutOfControl().getValue()),total));
+//            contentValues.put(DeviceAlarmEnum.OutOfControl.getText()+"比率",computeRatio(BigDecimal.valueOf(totalResult.getOutOfControl().getValue()),total));
             contentValues.put("镇痛不足比率",computeRatio(BigDecimal.valueOf(totalResult.getAnalgesicPoor().getValue()),total));
             contentValues.put("不在服务区比率",computeRatio(BigDecimal.valueOf(totalResult.getNoSignal().getValue()),total));
             contentValues.put(DeviceAlarmEnum.Machine.getText()+"比率",computeRatio(BigDecimal.valueOf(totalResult.getMachine().getValue()),total));
@@ -362,7 +362,7 @@ public class AlarmStatsAnalyse implements CommonStats<CombineAlarmResult> {
         resultMap.put(DeviceAlarmEnum.Jam,PieResult.of("jam",DeviceAlarmEnum.Jam.getText()+"原因分析饼图"));
         resultMap.put(DeviceAlarmEnum.Limit,PieResult.of("limit",DeviceAlarmEnum.Limit.getText()+"原因分析饼图"));
         resultMap.put(DeviceAlarmEnum.NotBox,PieResult.of("noBox",DeviceAlarmEnum.NotBox.getText()+"原因分析饼图"));
-        resultMap.put(DeviceAlarmEnum.OutOfControl,PieResult.of("outOfControl",DeviceAlarmEnum.OutOfControl.getText()+"原因分析饼图"));
+//        resultMap.put(DeviceAlarmEnum.OutOfControl,PieResult.of("outOfControl",DeviceAlarmEnum.OutOfControl.getText()+"原因分析饼图"));
         resultMap.put(DeviceAlarmEnum.Machine,PieResult.of("machine",DeviceAlarmEnum.Machine.getText()+"原因分析饼图"));
         resultMap.put(DeviceAlarmEnum.LowBattery,PieResult.of("lowBattery",DeviceAlarmEnum.LowBattery.getText()+"原因分析饼图"));
         resultMap.put(DeviceAlarmEnum.Bubble,PieResult.of("bubble",DeviceAlarmEnum.Bubble.getText()+"原因分析饼图"));

+ 11 - 11
nb-system/src/main/java/com/nb/bus/stats/entity/AlarmScatter.java

@@ -46,14 +46,14 @@ public class AlarmScatter extends LinkedHashMap<String, Map<String, AlarmScatter
         incrementValue(this.getNoBox(time));
     }
 
-    public AlarmScatter.AlarmStatsByTime getOutOfControl(String time) {
-        return this.computeIfAbsent(DeviceAlarmEnum.OutOfControl.getText(),k->new LinkedHashMap<>())
-                .computeIfAbsent(time,t->AlarmStatsByTime.of(time,0));
-    }
+//    public AlarmScatter.AlarmStatsByTime getOutOfControl(String time) {
+//        return this.computeIfAbsent(DeviceAlarmEnum.OutOfControl.getText(),k->new LinkedHashMap<>())
+//                .computeIfAbsent(time,t->AlarmStatsByTime.of(time,0));
+//    }
 
-    public void incrementOutOfControl(String time) {
-        incrementValue(this.getOutOfControl(time));
-    }
+//    public void incrementOutOfControl(String time) {
+//        incrementValue(this.getOutOfControl(time));
+//    }
 
 
     public AlarmScatter.AlarmStatsByTime getAnalgesicPoor(String time) {
@@ -184,9 +184,9 @@ public class AlarmScatter extends LinkedHashMap<String, Map<String, AlarmScatter
                 case Machine:
                     incrementMachine(time);
                     break;
-                case OutOfControl:
-                    incrementOutOfControl(time);
-                    break;
+//                case OutOfControl:
+//                    incrementOutOfControl(time);
+//                    break;
                 case LowBattery:
                     incrementLowBattery(time);
                     break;
@@ -245,7 +245,7 @@ public class AlarmScatter extends LinkedHashMap<String, Map<String, AlarmScatter
         getLimit(time);
         getNoBox(time);
         getMachine(time);
-        getOutOfControl(time);
+//        getOutOfControl(time);
         getLowBattery(time);
         getBubble(time);
         getInfusionMax(time);

+ 10 - 10
nb-system/src/main/java/com/nb/bus/stats/entity/AlarmTotalPieResult.java

@@ -58,13 +58,13 @@ public class AlarmTotalPieResult extends HashMap<String,PieContent> {
         incrementValue(this.getNoBox());
     }
 
-    public PieContent getOutOfControl() {
-        return this.computeIfAbsent("outOfControl",k->PieContent.of(DeviceAlarmEnum.OutOfControl.getText(),0L));
-    }
+//    public PieContent getOutOfControl() {
+//        return this.computeIfAbsent("outOfControl",k->PieContent.of(DeviceAlarmEnum.OutOfControl.getText(),0L));
+//    }
 
-    public void incrementOutOfControl() {
-        incrementValue(this.getOutOfControl());
-    }
+//    public void incrementOutOfControl() {
+//        incrementValue(this.getOutOfControl());
+//    }
 
 
     public PieContent getAnalgesicPoor() {
@@ -178,7 +178,7 @@ public class AlarmTotalPieResult extends HashMap<String,PieContent> {
         getJam();
         getLimit();
         getNoBox();
-        getOutOfControl();
+//        getOutOfControl();
         getAnalgesicPoor();
         getNoSignal();
         getMachine();
@@ -211,9 +211,9 @@ public class AlarmTotalPieResult extends HashMap<String,PieContent> {
                 case Machine:
                     incrementMachine();
                     break;
-                case OutOfControl:
-                    incrementOutOfControl();
-                    break;
+//                case OutOfControl:
+//                    incrementOutOfControl();
+//                    break;
                 case LowBattery:
                     incrementLowBattery();
                     break;

+ 66 - 0
nb-system/src/main/java/com/nb/system/config/DefaultApplyManager.java

@@ -0,0 +1,66 @@
+package com.nb.system.config;
+
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.core.util.StrUtil;
+import com.nb.common.apply.ApplyManager;
+import com.nb.common.cache.ConfigStorage;
+import com.nb.common.cache.manager.ClusterConfigStorageManager;
+import org.springframework.stereotype.Component;
+import org.tio.utils.crypto.Md5;
+
+import java.util.Collection;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName DefaultAppMananger.java
+ * @Description TODO
+ * @createTime 2022年07月27日 11:10:00
+ */
+@Component
+public class DefaultApplyManager implements ApplyManager {
+    private final ConfigStorage storage;
+
+    public DefaultApplyManager(ClusterConfigStorageManager clusterConfigStorageManager) {
+        storage = clusterConfigStorageManager.getStorage("apply");
+    }
+
+    @Override
+    public String generateAppKey(Long timestamp) {
+        return String.valueOf(timestamp)+RandomUtil.randomInt(3);
+    }
+
+    @Override
+    public String generateAppSecret(String appKey) {
+        return Md5.getMD5(appKey+ RandomUtil.randomString(3));
+    }
+
+    @Override
+    public String getAppSecret(String appKey) {
+        String value = storage.getConfig(appKey).asString();
+        if(StrUtil.isNullOrUndefined(value)){
+            return null;
+        }
+        return value.split(";")[0];
+    }
+
+    @Override
+    public void setApply(String appKey, String appSecret,String tenantId) {
+        String value=appSecret+";"+tenantId;
+        storage.setConfig(appKey,value);
+    }
+
+    @Override
+    public String getTenantId(String appKey) {
+        String value = storage.getConfig(appKey).asString();
+        if(StrUtil.isNullOrUndefined(value)){
+            return null;
+        }
+        return value.split(";")[1];
+    }
+
+    @Override
+    public Collection<String> getPermission(String appKey) {
+        return null;
+    }
+}

+ 3 - 5
nb-system/src/main/java/com/nb/system/controller/SysApplyController.java

@@ -4,11 +4,9 @@ import cn.dev33.satoken.SaManager;
 import cn.dev33.satoken.stp.StpLogic;
 import com.baomidou.mybatisplus.core.mapper.Mapper;
 import com.nb.common.crud.BaseService;
-import com.nb.common.crud.controller.BaseQueryController;
+import com.nb.common.crud.controller.BaseCrudController;
 import com.nb.system.entity.SysApply;
-import com.nb.system.entity.SysRunningLog;
 import com.nb.system.service.impl.LocalSysApplyService;
-import com.nb.system.service.impl.LocalSysRunningLogService;
 import io.swagger.annotations.Api;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -19,7 +17,7 @@ import org.springframework.web.bind.annotation.RestController;
  * @author lifang
  * @version 1.0.0
  * @ClassName SysRunningLogController.java
- * @Description TODO
+ * @Description 第三方应用app接入管理
  * @createTime 2022年07月11日 11:04:00
  */
 @RestController
@@ -27,7 +25,7 @@ import org.springframework.web.bind.annotation.RestController;
 @RequestMapping("/sys/apply")
 @Slf4j
 @Api(tags = "第三方应用app接入管理",description = "第三方应用app接入管理 ,权限前缀【sys:apply:】,如查询【sys:apply:query】")
-public class SysApplyController implements BaseQueryController<SysApply,String> {
+public class SysApplyController extends BaseCrudController<SysApply,String> {
     private final LocalSysApplyService sysApplyService;
     @Override
     public BaseService<? extends Mapper<SysApply>, SysApply, String> getService() {

+ 4 - 0
nb-system/src/main/java/com/nb/system/entity/SysApply.java

@@ -1,5 +1,7 @@
 package com.nb.system.entity;
 
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
@@ -30,10 +32,12 @@ import javax.validation.constraints.NotNull;
 public class SysApply  extends TenantGenericEntity<String,String> {
     @ApiModelProperty("appKey,用于接入换取token,自动生成,无需传入")
     @JsonSetter
+    @TableField(updateStrategy = FieldStrategy.NEVER)
     private String appKey;
 
     @ApiModelProperty("appSecret,用于接入换取token,自动生成,无需传入")
     @JsonSetter
+    @TableField(updateStrategy = FieldStrategy.NEVER)
     private String appSecret;
 
     @ApiModelProperty("第三方应用名称,必填")

+ 39 - 2
nb-system/src/main/java/com/nb/system/service/impl/LocalSysApplyService.java

@@ -1,8 +1,13 @@
 package com.nb.system.service.impl;
 
+import cn.hutool.core.util.StrUtil;
+import com.nb.common.apply.ApplyManager;
 import com.nb.common.crud.BaseService;
+import com.nb.common.exception.CustomException;
 import com.nb.system.entity.SysApply;
 import com.nb.system.mapper.SysApplyMapper;
+import lombok.AllArgsConstructor;
+import org.springframework.boot.CommandLineRunner;
 import org.springframework.stereotype.Service;
 
 /**
@@ -13,10 +18,27 @@ import org.springframework.stereotype.Service;
  * @createTime 2022年07月11日 11:02:00
  */
 @Service
-public class LocalSysApplyService extends BaseService<SysApplyMapper, SysApply,String> {
+@AllArgsConstructor
+public class LocalSysApplyService extends BaseService<SysApplyMapper, SysApply,String> implements CommandLineRunner {
+    private final ApplyManager applyManager;
     @Override
     public void validateBeforeSave(SysApply entity) {
-
+        boolean validate=false;
+        String appKey = null;
+        for (int i = 0; i < 10; i++) {
+            appKey=applyManager.generateAppKey(System.currentTimeMillis());
+            String appSecret = applyManager.getAppSecret(appKey);
+            if(StrUtil.isNullOrUndefined(appSecret)){
+                validate=true;
+                break;
+            }
+        }
+        if(!validate){
+            throw new CustomException("系统繁忙,请稍后再试");
+        }
+        String appSecret = applyManager.getAppSecret(appKey);
+        entity.setAppKey(appKey);
+        entity.setAppSecret(appSecret);
     }
 
     @Override
@@ -28,4 +50,19 @@ public class LocalSysApplyService extends BaseService<SysApplyMapper, SysApply,S
     public void validateBeforeDelete(String id) {
 
     }
+
+    /**
+     * 保存成功后操作
+     */
+    @Override
+    public void postSave(SysApply  entity){
+        applyManager.setApply(entity.getAppKey(),entity.getAppSecret());
+    }
+
+
+    @Override
+    public void run(String... args) {
+        this.list().parallelStream()
+                .forEach(apply-> applyManager.setApply(apply.getAppKey(),apply.getAppSecret()));
+    }
 }