Prechádzať zdrojové kódy

Merge remote-tracking branch 'origin/develop' into test

songxinlu 3 rokov pred
rodič
commit
8c1cc5c89e

+ 9 - 0
doc/038.20211129_2.1.3/qc_initv2.1.3.sql

@@ -0,0 +1,9 @@
+
+use `qc`;
+-- 执行前请看注意事项!
+-- 通用版本token有效时间配置化
+/**
+sys_dictionary_info表新增token时间配置
+ */
+INSERT INTO `sys_dictionary_info` (`group_type`, `name`, `val`, `return_type`, `remark`) VALUES ('31', 'accessToken', '86400', '2', 'accessToken有效期(单位秒)');
+INSERT INTO `sys_dictionary_info` (`group_type`, `name`, `val`, `return_type`, `remark`) VALUES ('31', 'refreshToken', '604800', '2', 'refreshToken有效期(单位秒)');

+ 43 - 0
src/main/java/com/diagbot/config/AuthExceptionEntryPoint.java

@@ -0,0 +1,43 @@
+package com.diagbot.config;
+
+import com.diagbot.util.StringUtil;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.web.AuthenticationEntryPoint;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @Description:
+ * @Author songxl
+ * @Date 2021/11/30
+ */
+public class AuthExceptionEntryPoint implements AuthenticationEntryPoint {
+
+
+    @Override
+    public void commence(HttpServletRequest request, HttpServletResponse response,
+                         AuthenticationException authException)
+            throws ServletException {
+        Map map = new HashMap();
+        if (StringUtil.isNotEmpty(authException.getMessage())&&authException.getMessage().contains("Access token expired")) {
+            map.put("code", "10020011");
+            map.put("msg", "登录超时。为确保您的账户安全,系统已自动退出,请重新登录。");
+        }else {
+            map.put("code", "00000001");
+            map.put("msg", authException.getMessage());
+        }
+        response.setContentType("application/json");
+        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+        try {
+            ObjectMapper mapper = new ObjectMapper();
+            mapper.writeValue(response.getOutputStream(), map);
+        } catch (Exception e) {
+            throw new ServletException();
+        }
+    }
+}

+ 14 - 2
src/main/java/com/diagbot/config/OAuth2Configurer.java

@@ -1,5 +1,6 @@
 package com.diagbot.config;
 
+import com.diagbot.facade.SysDictionaryFacade;
 import com.diagbot.service.UrlUserService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -33,17 +34,28 @@ import java.util.Arrays;
 public class OAuth2Configurer extends AuthorizationServerConfigurerAdapter {
     @Autowired
     private UrlUserService urlUserService;
+    @Autowired
+    private SysDictionaryFacade sysDictionaryFacade;
 
     @Override
     public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
+        int accessToken = 24 * 3600;
+        int refreshToken = 30 * 24 * 3600;
+        if (sysDictionaryFacade.getDictionaryWithKey() != null
+                && sysDictionaryFacade.getDictionaryWithKey().containsKey("31")
+                && sysDictionaryFacade.getDictionaryWithKey().get("31").containsKey("accessToken")
+                && sysDictionaryFacade.getDictionaryWithKey().get("31").containsKey("refreshToken")) {
+            accessToken = Integer.parseInt(sysDictionaryFacade.getDictionaryWithKey().get("31").get("accessToken"));
+            refreshToken = Integer.parseInt(sysDictionaryFacade.getDictionaryWithKey().get("31").get("refreshToken"));
+        }
         clients.inMemory()
                 .withClient("uaa-service")
                 .secret("{noop}123456")
                 .scopes("service")
                 .autoApprove(true)
                 .authorizedGrantTypes("implicit", "refresh_token", "password", "authorization_code")
-                .accessTokenValiditySeconds(24 * 3600)
-                .refreshTokenValiditySeconds(30 * 24 * 3600);
+                .accessTokenValiditySeconds(accessToken)
+                .refreshTokenValiditySeconds(refreshToken);
     }
 
     /**

+ 4 - 0
src/main/java/com/diagbot/config/ResourceServerConfigurer.java

@@ -13,6 +13,7 @@ import org.springframework.security.jwt.crypto.sign.RsaVerifier;
 import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
 import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
 import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
+import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint;
 import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
 import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
 import org.springframework.util.FileCopyUtils;
@@ -33,6 +34,8 @@ public class ResourceServerConfigurer extends ResourceServerConfigurerAdapter {
     @Override
     public void configure(HttpSecurity http) throws Exception {
         http.cors()
+                .and()
+                .exceptionHandling().authenticationEntryPoint(new AuthExceptionEntryPoint())
                 .and()
                 .csrf().disable()
                 .authorizeRequests()
@@ -271,6 +274,7 @@ public class ResourceServerConfigurer extends ResourceServerConfigurerAdapter {
     public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
         log.info("Configuring ResourceServerSecurityConfigurer");
         resources.resourceId("user-service").tokenStore(new JwtTokenStore(jwtTokenEnhancerClient()));
+        resources.authenticationEntryPoint(new AuthExceptionEntryPoint());
     }
     @Autowired
     private CustomAccessTokenConverter customAccessTokenConverter;

+ 41 - 3
src/main/java/com/diagbot/config/security/UrlAccessDecisionManager.java

@@ -1,5 +1,8 @@
 package com.diagbot.config.security;
 
+import com.diagbot.exception.CommonErrorCode;
+import com.diagbot.exception.CommonException;
+import com.diagbot.exception.ServiceErrorCode;
 import com.diagbot.facade.TokenFacade;
 import com.diagbot.util.HttpUtils;
 import com.diagbot.util.StringUtil;
@@ -32,17 +35,28 @@ public class UrlAccessDecisionManager implements AccessDecisionManager {
     public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
         HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
         String url, method;
+        String tokenStr = HttpUtils.getHeaders(request).get("Authorization");
+        //用户是否被顶掉校验
+        if (StringUtil.isNotEmpty(tokenStr) && !matchNotCheckUrl(request)) {
+            tokenStr = tokenStr.replaceFirst("Bearer ", "");
+            int res = tokenFacade.newVerifyToken(tokenStr, 1);
+            if (-1 == res) {
+                throw new CommonException(ServiceErrorCode.LONGIN_ERROE);
+            }
+        }
         if (matchPermitAllUrl(request)) {
             return;
         }
         if ("anonymousUser".equals(authentication.getPrincipal())) {
             throw new AccessDeniedException("no right");
         } else {
-            String tokenStr = HttpUtils.getHeaders(request).get("Authorization");
             if (StringUtil.isNotEmpty(tokenStr)) {
                 tokenStr = tokenStr.replaceFirst("Bearer ", "");
-                Boolean res = tokenFacade.verifyToken(tokenStr, 1);
-                if (!res) {
+//                Boolean res = tokenFacade.verifyToken(tokenStr, 1);
+                int res = tokenFacade.newVerifyToken(tokenStr, 1);
+                if (-1 == res) {
+                    throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "该账号在其他地方登录。");
+                } else if (1 != res) {
                     throw new AccountExpiredException("token expire");
                 }
             }
@@ -321,4 +335,28 @@ public class UrlAccessDecisionManager implements AccessDecisionManager {
         }
         return false;
     }
+    private boolean matchNotCheckUrl(HttpServletRequest request) {
+        if (matchers("/swagger/**", request)
+                || matchers("/v2/**", request)
+                || matchers("/swagger-ui.html/**", request)
+                || matchers("/swagger-resources/**", request)
+                || matchers("/webjars/**", request)
+                || matchers("/druid/**", request)
+                || matchers("/actuator/**", request)
+                || matchers("/hystrix/**", request)
+                || matchers("/sys/user/getJwt", request)
+                || matchers("/sys/user/logout", request)
+                || matchers("/sys/user/getCaptcha", request)
+                || matchers("/sys/user/getHospitalMark", request)
+                || matchers("/sys/user/getJwtNoPass", request)
+                || matchers("/sys/user/refreshJwt", request)
+                || matchers("/sys/dictionaryInfo/getDictionary", request)
+                || matchers("/sys/user/checkToken", request)
+                || matchers("/oauth/token", request)
+                || matchers("/oauth/check_token", request)
+                || matchers("/cache/clear", request)) {
+            return true;
+        }
+        return false;
+    }
 }

+ 13 - 1
src/main/java/com/diagbot/config/security/UrlFilterSecurityInterceptor.java

@@ -1,5 +1,7 @@
 package com.diagbot.config.security;
 
+import com.alibaba.fastjson.JSONObject;
+import com.diagbot.exception.CommonException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.SecurityMetadataSource;
 import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
@@ -43,7 +45,17 @@ public class UrlFilterSecurityInterceptor extends AbstractSecurityInterceptor im
     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
 
         FilterInvocation fi = new FilterInvocation(request, response, chain);
-        invoke(fi);
+        try {
+            invoke(fi);
+        }catch (CommonException e)
+        {
+            JSONObject error = new JSONObject();
+            response.setContentType("text/html;charset=utf-8");
+            error.put("code",e.getCode());
+            error.put("msg", e.getMessage());
+            response.getWriter().println(error);
+            response.flushBuffer();
+        }
     }
 
 

+ 6 - 0
src/main/java/com/diagbot/entity/MedQcresultCases.java

@@ -2,6 +2,7 @@ package com.diagbot.entity;
 
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
 
 import java.io.Serializable;
 import java.math.BigDecimal;
@@ -15,6 +16,7 @@ import java.util.Date;
  * @author gaodm
  * @since 2020-05-19
  */
+@Data
 public class MedQcresultCases implements Serializable {
 
     private static final long serialVersionUID = 1L;
@@ -26,6 +28,10 @@ public class MedQcresultCases implements Serializable {
      * 医院ID
      */
     private Long hospitalId;
+    /**
+     * 评分结果ID
+     */
+    private Long qcresultInfoId;
 
     /**
      * 病人住院ID

+ 4 - 0
src/main/java/com/diagbot/entity/QcresultDetail.java

@@ -31,6 +31,10 @@ public class QcresultDetail implements Serializable {
      * 医院ID
      */
     private Long hospitalId;
+    /**
+     * 评分结果ID
+     */
+    private Long qcresultInfoId;
 
     /**
      * 病人住院ID

+ 1 - 0
src/main/java/com/diagbot/exception/ServiceErrorCode.java

@@ -12,6 +12,7 @@ public enum ServiceErrorCode implements ErrorCode {
     USER_PASSWORD_ERROR("10020001", "账号或密码不正确"),
     GET_TOKEN_FAIL("10020002", "获取token失败"),
     TOKEN_IS_NOT_MATCH_USER("10020003", "请使用自己的token进行接口请求"),
+    LONGIN_ERROE("10020012", "您的账号在其它地方已登录,您已被迫下线,请重新登录。如非本人授权,登录后请及时修改密码。"),
 
     SMS_SEND_ERROR("10020004", "短信发送错误"),
     USER_BIND_ERROR("10020005", "用户手机号已经绑定无需再次验证"),

+ 79 - 9
src/main/java/com/diagbot/facade/BehospitalInfoFacade.java

@@ -22,6 +22,7 @@ import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.ibatis.annotations.Param;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
@@ -149,6 +150,9 @@ public class BehospitalInfoFacade extends BehospitalInfoServiceImpl {
     SysUserRoleFacade sysUserRoleFacade;
     @Autowired
     MedClickInfoServiceImpl medClickInfoService;
+    @Autowired
+    QcresultDetailFacade qcresultDetailFacade;
+
 
 
     /**
@@ -1054,14 +1058,14 @@ public class BehospitalInfoFacade extends BehospitalInfoServiceImpl {
         QueryVo queryVo = dealCommonData(hospitalId, analyzeVO);
         queryVo.setUseCrfCache(analyzeVO.isUseCrfCache());
         //已核查抛出以评分
-        List<MedCheckInfo> medCheckInfos = medCheckInfoFacade.list(new QueryWrapper<MedCheckInfo>()
-                .eq("is_deleted", IsDeleteEnum.N.getKey())
-                .eq("hospital_id", analyzeVO.getHospitalId())
-                .eq("behospital_code", analyzeVO.getBehospitalCode()));
-        Set<Integer> status = medCheckInfos.stream().map(MedCheckInfo::getStatus).collect(Collectors.toSet());
-        if (medCheckInfos.size() >= 1 && status.contains(CheckStatusEnum.Enable.getKey()) && analyzeVO.getCheckFlag()) {
-            throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "该病例已经核查无需评分!");
-        }
+//        List<MedCheckInfo> medCheckInfos = medCheckInfoFacade.list(new QueryWrapper<MedCheckInfo>()
+//                .eq("is_deleted", IsDeleteEnum.N.getKey())
+//                .eq("hospital_id", analyzeVO.getHospitalId())
+//                .eq("behospital_code", analyzeVO.getBehospitalCode()));
+//        Set<Integer> status = medCheckInfos.stream().map(MedCheckInfo::getStatus).collect(Collectors.toSet());
+//        if (medCheckInfos.size() >= 1 && status.contains(CheckStatusEnum.Enable.getKey()) && analyzeVO.getCheckFlag()) {
+//            throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "该病例已经核查无需评分!");
+//        }
         //  调用质控接口
         Response<OutputInfo> response = qcServiceClient.extract(queryVo);
         if (response == null || response.getData() == null) {
@@ -2257,6 +2261,10 @@ public class BehospitalInfoFacade extends BehospitalInfoServiceImpl {
                                                String isPlacefile) {
         Long hospitalId = analyzeVO.getHospitalId();
         List<QcResultAlgVO> qcResultAlgVOList = new ArrayList<>();
+        //获取本用户原手动添加的扣分条目(删除|未删除)
+        List<QcCasesEntry> qcCasesEntryHistory = new ArrayList<>();
+        List<QcresultDetail> qcresultDetails = getQcDetailHistory(analyzeVO, codeList, qcCasesEntryHistory);
+        Map<Long, List<QcCasesEntry>> qcCasesEntryHistoryMap = qcCasesEntryHistory.stream().collect(Collectors.groupingBy(QcCasesEntry::getId));
         if (ListUtil.isNotEmpty(codeList)) {
             // 根据质控结果获取质控条目
             QcResultAlgQueryVO qcResultAlgQueryVO = new QcResultAlgQueryVO();
@@ -2273,6 +2281,25 @@ public class BehospitalInfoFacade extends BehospitalInfoServiceImpl {
                 bean.setInfo(info);
             }
         }
+        //1.1未删除的手工评分
+        List<QcResultAlgVO> rgQcResultAlgVOList = new ArrayList<>();
+        if (qcresultDetails != null) {
+            List<QcresultDetail> notDelQcDetailHistory = qcresultDetails.stream()
+                    .filter(qcresultDetail -> "N".equals(qcresultDetail.getIsDeleted())).collect(Collectors.toList());
+            if (ListUtil.isNotEmpty(notDelQcDetailHistory)) {
+                notDelQcDetailHistory.stream().forEach(qcresultDetail -> {
+                    QcResultAlgVO temp = new QcResultAlgVO();
+                    BeanUtils.copyProperties(qcresultDetail, temp);
+                    try {
+                        temp.setCode(qcCasesEntryHistoryMap.get(qcresultDetail.getCasesEntryId()).get(0).getCode());
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                    rgQcResultAlgVOList.add(temp);
+                });
+            }
+            qcResultAlgVOList.addAll(rgQcResultAlgVOList);
+        }
 
         // 评分
         AlgorithmVO algorithmVO = new AlgorithmVO();
@@ -2354,6 +2381,8 @@ public class BehospitalInfoFacade extends BehospitalInfoServiceImpl {
         String menuData = JSON.toJSONString(qcModeDTOList);
 
         // 保存评分结果信息
+        //计分删除人工添加条目
+        algorithmVO.getQcResultAlgVOList().removeAll(rgQcResultAlgVOList);
         Date date = qcresultInfoFacade.saveQcResult(algorithmDTO, algorithmVO, analyzeVO, pageData, menuData, analyzeVO.getIsTask(), null);
 
         // 返回结果信息
@@ -2511,5 +2540,46 @@ public class BehospitalInfoFacade extends BehospitalInfoServiceImpl {
 
         return behospitalInfoAgeDTOList;
     }
-
+    /**
+     * @param analyzeVO
+     * @param codeList
+     * @Description获取原手动扣分分值条目
+     * @Return void
+     */
+    private List<QcresultDetail> getQcDetailHistory(AnalyzeVO analyzeVO, List<String> codeList, List<QcCasesEntry> qcCasesEntryHistory) {
+        List<QcresultDetail> qcresultDetails = null;
+        try {
+            QcresultInfo qcresultInfoup
+                    = qcresultInfoFacade.getOne(
+                    new QueryWrapper<QcresultInfo>()
+                            .eq("is_deleted", IsDeleteEnum.N.getKey())
+                            .eq("hospital_id", analyzeVO.getHospitalId())
+                            .eq("behospital_code", analyzeVO.getBehospitalCode()), false);
+            //未评过分
+            if (qcresultInfoup == null) {
+                return null;
+            }
+            //1.获取上一次评分手工添加的条目
+            qcresultDetails = qcresultDetailFacade.list(new QueryWrapper<QcresultDetail>()
+                    .eq("hospital_id", analyzeVO.getHospitalId())
+                    .eq("behospital_code", analyzeVO.getBehospitalCode())
+                    .eq("grade_type", "2")
+                    .eq("qcresult_info_id", qcresultInfoup.getId()));
+            List<Long> qcDetailIDHistory = qcresultDetails.stream().map(QcresultDetail::getCasesEntryId).collect(Collectors.toList());
+
+            if (ListUtil.isNotEmpty(qcDetailIDHistory)) {
+                List<QcCasesEntry> qcCasesEntries = qcCasesEntryFacade.list(new QueryWrapper<QcCasesEntry>()
+                        .select("id,code")
+                        .eq("is_deleted", IsDeleteEnum.N.getKey())
+                        .in("id", qcDetailIDHistory));
+                if (ListUtil.isNotEmpty(qcCasesEntries)) {
+                    qcCasesEntryHistory.addAll(qcCasesEntries);
+                    codeList.removeAll(qcCasesEntryHistory.stream().map(QcCasesEntry::getCode).collect(Collectors.toList()));
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return qcresultDetails;
+    }
 }

+ 88 - 28
src/main/java/com/diagbot/facade/QcresultInfoFacade.java

@@ -149,12 +149,18 @@ public class QcresultInfoFacade extends QcresultInfoServiceImpl {
             try {
                 useId = Long.valueOf(SysUserUtils.getCurrentPrincipleID());
             } catch (Exception e) {
-            //analyze_run运行质控没有登录认证   所以会获取不到
+                //analyze_run运行质控没有登录认证   所以会获取不到
                 useId = 952795279527L;
             }
         }
+        //获取上一次人工添加的缺陷
+        QcresultInfo qcresultInfoup
+                = this.getOne(
+                new QueryWrapper<QcresultInfo>()
+                        .eq("is_deleted", IsDeleteEnum.N.getKey())
+                        .eq("hospital_id", analyzeVO.getHospitalId())
+                        .eq("behospital_code", analyzeVO.getBehospitalCode()), false);
         Date now = DateUtil.now();
-        //逻辑删除记录
         this.update(new UpdateWrapper<QcresultInfo>()
                 .eq("is_deleted", IsDeleteEnum.N.getKey())
                 .eq("hospital_id", analyzeVO.getHospitalId())
@@ -192,16 +198,43 @@ public class QcresultInfoFacade extends QcresultInfoServiceImpl {
         qcresultInfo.setGmtModified(now);
         qcresultInfo.setModifier(useId.toString());
         this.save(qcresultInfo);
+        Long newId = qcresultInfo.getId();
         //更新质控评分明细信息
         switch (algorithmVO.getType()) {
             //自动评分
             case 0:
                 //删除记录
-                qcresultDetailServiceImpl.remove(new QueryWrapper<QcresultDetail>()
+//                qcresultDetailServiceImpl.remove(new QueryWrapper<QcresultDetail>()
+//                        .eq("hospital_id", analyzeVO.getHospitalId())
+//                        .eq("behospital_code", analyzeVO.getBehospitalCode()));
+
+                //上一次人工评分条目
+                List<QcresultDetail> oldQcresultDetails = null;
+                if (qcresultInfoup != null) {
+                    oldQcresultDetails = qcresultDetailServiceImpl.list(new QueryWrapper<QcresultDetail>()
+                            .eq("hospital_id", analyzeVO.getHospitalId())
+                            .eq("qcresult_info_id", qcresultInfoup.getId())
+                            .eq("grade_type", "2")
+                            .eq("behospital_code", analyzeVO.getBehospitalCode()));
+                }
+
+                qcresultDetailServiceImpl.update(new UpdateWrapper<QcresultDetail>()
+                        .eq("is_deleted", IsDeleteEnum.N.getKey())
                         .eq("hospital_id", analyzeVO.getHospitalId())
-                        .eq("behospital_code", analyzeVO.getBehospitalCode()));
+                        .eq("behospital_code", analyzeVO.getBehospitalCode())
+                        .set("is_deleted", IsDeleteEnum.Y.getKey())
+                        .set("modifier", useId)
+                        .set("gmt_modified", now));
+                //
                 //批量插入新的数据
                 List<QcresultDetail> qcresultDetailList = new ArrayList<>();
+                if (ListUtil.isNotEmpty(oldQcresultDetails)) {
+                    qcresultDetailList.addAll(oldQcresultDetails);
+                    qcresultDetailList.forEach(qcresultDetail -> {
+                        //原手动添加缺陷绑定新机器评分id
+                        qcresultDetail.setQcresultInfoId(newId);
+                    });
+                }
                 List<QcResultAlgVO> qcResultAlgVORes = algorithmVO.getQcResultAlgVOList();
                 if (ListUtil.isNotEmpty(qcResultAlgVORes)) {
                     for (QcResultAlgVO qcResultAlgVO : qcResultAlgVORes) {
@@ -216,6 +249,7 @@ public class QcresultInfoFacade extends QcresultInfoServiceImpl {
                         qcresultDetail.setGmtModified(now);
                         qcresultDetail.setModifier(useId.toString());
                         qcresultDetail.setInfo(StringUtil.isNotBlank(qcResultAlgVO.getInfo()) ? qcResultAlgVO.getInfo() : "");
+                        qcresultDetail.setQcresultInfoId(newId);
                         qcresultDetailList.add(qcresultDetail);
                     }
                     qcresultDetailServiceImpl.saveBatch(qcresultDetailList);
@@ -233,6 +267,7 @@ public class QcresultInfoFacade extends QcresultInfoServiceImpl {
                 qcresultDetailAdd.setCreator(useId.toString());
                 qcresultDetailAdd.setGmtModified(now);
                 qcresultDetailAdd.setModifier(useId.toString());
+                qcresultDetailAdd.setQcresultInfoId(newId);
                 qcresultDetailServiceImpl.save(qcresultDetailAdd);
                 break;
             case 2:
@@ -253,44 +288,44 @@ public class QcresultInfoFacade extends QcresultInfoServiceImpl {
                         .set("msg", algorithmVO.getOptResultAlgVO().getMsg())
                         .set("score", algorithmVO.getOptResultAlgVO().getScore())
                         .set("opt_type", 3)
-                        .set("grade_type",2)
+                        .set("grade_type", 2)
                         .set("modifier", useId)
+                        .set("qcresult_info_id", newId)
                         .set("gmt_modified", now)
-                        .set("explain_info",algorithmVO.getOptResultAlgVO().getExplainInfo())
+                        .set("explain_info", algorithmVO.getOptResultAlgVO().getExplainInfo())
                 );
                 break;
             case 4:
                 //获取病历核查人员id,该操作只能是核查员操作
-                Long checkId = medCheckInfoFacade.getOne(new QueryWrapper<MedCheckInfo>()
-                        .eq("is_deleted", IsDeleteEnum.N.getKey())
-                        .eq("hospital_id", analyzeVO.getHospitalId())
-                        .eq("behospital_code", analyzeVO.getBehospitalCode())).getCheckId();
-                if(checkId==null)
-                {
-                    throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "病历没有分配核查人员");
-                }
-                if(!checkId.equals(useId))
-                {
-                    throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "当前用户不是分配的核查人员");
-                }
+//                Long checkId = medCheckInfoFacade.getOne(new QueryWrapper<MedCheckInfo>()
+//                        .eq("is_deleted", IsDeleteEnum.N.getKey())
+//                        .eq("hospital_id", analyzeVO.getHospitalId())
+//                        .eq("behospital_code", analyzeVO.getBehospitalCode())).getCheckId();
+//                if(checkId==null)
+//                {
+//                    throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "病历没有分配核查人员");
+//                }
+//                if(!checkId.equals(useId))
+//                {
+//                    throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "当前用户不是分配的核查人员");
+//                }
                 //逻辑删除质控明细 0删除
-                if(analyzeVO.getDelStatus()==0)
-                {
+                if (analyzeVO.getDelStatus() == 0) {
                     qcresultDetailServiceImpl.update(new UpdateWrapper<QcresultDetail>()
                             .eq("id", algorithmVO.getOptResultAlgVO().getId())
                             .eq("is_deleted", IsDeleteEnum.N.getKey())
                             .eq("hospital_id", analyzeVO.getHospitalId())
                             .eq("behospital_code", analyzeVO.getBehospitalCode())
                             .set("is_deleted", IsDeleteEnum.Y.getKey())
-                            .set("grade_type",2)
+                            .set("grade_type", 2)
                             .set("opt_type", 2)
+                            .set("qcresult_info_id", newId)
                             .set("modifier", useId)
                             .set("gmt_modified", now)
                     );
                 }
                 //1恢复
-                else if(analyzeVO.getDelStatus()==1)
-                {
+                else if (analyzeVO.getDelStatus() == 1) {
                     //该条目是机器插入条目
                     qcresultDetailServiceImpl.update(new UpdateWrapper<QcresultDetail>()
                             .eq("id", algorithmVO.getOptResultAlgVO().getId())
@@ -298,24 +333,48 @@ public class QcresultInfoFacade extends QcresultInfoServiceImpl {
                             .eq("hospital_id", analyzeVO.getHospitalId())
                             .eq("behospital_code", analyzeVO.getBehospitalCode())
                             .set("is_deleted", IsDeleteEnum.N.getKey())
-                            .set("grade_type",2)
+                            .set("grade_type", 2)
                             .set("opt_type", 1)
+                            .set("qcresult_info_id", newId)
                             .set("modifier", useId)
                             .set("remark", null)
                             .set("gmt_modified", now)
                     );
-                }
-                else {
+                } else {
                     throw new CommonException(CommonErrorCode.PARAM_IS_ERROR, "delStatus参数错误");
                 }
-
-
                 break;
             default:
                 /* DO NOTHING */
                 break;
         }
 
+        //如果不是自动评分(是新增修改删除条目)修改评分主表id
+        if (algorithmVO.getType() != 0) {
+            //修改上一次人工条目 评分主表id
+            if (qcresultInfoup != null && qcresultInfoup.getId() != null) {
+                qcresultDetailServiceImpl.update(new UpdateWrapper<QcresultDetail>()
+                        .eq("qcresult_info_id", qcresultInfoup.getId())
+                        .eq("hospital_id", analyzeVO.getHospitalId())
+                        .eq("grade_type", 2)
+                        .eq("behospital_code", analyzeVO.getBehospitalCode())
+                        .set("qcresult_info_id", newId)
+                        .set("modifier", useId)
+                        .set("gmt_modified", now)
+                );
+            }
+            //未删除的 评分主表id
+            qcresultDetailServiceImpl.update(new UpdateWrapper<QcresultDetail>()
+                    .eq("is_deleted", IsDeleteEnum.N.getKey())
+                    .eq("hospital_id", analyzeVO.getHospitalId())
+                    .eq("behospital_code", analyzeVO.getBehospitalCode())
+                    .set("qcresult_info_id", newId)
+                    .set("modifier", useId)
+                    .set("gmt_modified", now)
+            );
+        }
+
+
         //质控模块评分数据
         //统一为长兴的算法
         //逻辑删除数据
@@ -337,6 +396,7 @@ public class QcresultInfoFacade extends QcresultInfoServiceImpl {
                 medQcresultCases.setCreator(useId.toString());
                 medQcresultCases.setGmtModified(now);
                 medQcresultCases.setModifier(useId.toString());
+                medQcresultCases.setQcresultInfoId(newId);
                 medQcresultCasesList.add(medQcresultCases);
             }
             medQcresultCasesService.saveBatch(medQcresultCasesList);

+ 8 - 0
src/main/java/com/diagbot/service/SysTokenService.java

@@ -27,6 +27,14 @@ public interface SysTokenService {
      * @return
      */
     Boolean verifyToken(String token, Integer type);
+    /**
+     * 验证token是否有效
+     *
+     * @param token 待验证的token
+     * @param type  1:accessToken,2:refreshToken
+     * @return
+     */
+    int newVerifyToken(String token, Integer type);
 
     /**
      * 删除用户token

+ 54 - 0
src/main/java/com/diagbot/service/impl/SysTokenServiceImpl.java

@@ -127,6 +127,60 @@ public class SysTokenServiceImpl implements SysTokenService {
         return res;
     }
 
+    /**
+     * 验证token是否有效
+     *
+     * @param token 待验证的token
+     * @param type  1:accessToken,2:refreshToken
+     * @return -1:token无效(与服务器token不一致,异地登录),1:token有效,0:其他
+     */
+    @Override
+    public int newVerifyToken(String token, Integer type) {
+        Integer res = 0;
+        if (null == token) {
+            return 0;
+        }
+        String userId = JwtUtil.getUserId(token);
+        //从redis中取出
+        final byte[] redis_key = getUserTokenKey(userId);
+        JwtStore tokenStore = (JwtStore) redisForToken.execute(new RedisCallback<JwtStore>() {
+            @Override
+            public JwtStore doInRedis(RedisConnection connection) throws DataAccessException {
+                byte[] bytes = connection.get(redis_key);
+                if (bytes == null) {
+                    return null;
+                }
+                return (JwtStore) deserializeValue(bytes);
+            }
+        });
+
+        if (null != tokenStore) {
+            if (type == 1) {
+                if (null != tokenStore.getAccessToken()) {
+                    if (tokenStore.getAccessToken().equals(token)) {
+                        res = 1;
+                    } else {
+                        res = -1;
+                    }
+                }
+            }
+
+            if (type == 2) {
+                if (null != tokenStore.getRefreshToken()) {
+                    if (tokenStore.getRefreshToken().equals(token)) {
+                        res = 1;
+                    } else {
+                        res = -1;
+                    }
+                }
+            }
+        } else {
+            res = -1;
+        }
+
+        return res;
+    }
+
     /**
      * 删除用户token
      *

+ 1 - 0
src/main/resources/mapper/MedQcresultCasesMapper.xml

@@ -7,6 +7,7 @@
         <id column="id" property="id" />
         <result column="hospital_id" property="hospitalId" />
         <result column="behospital_code" property="behospitalCode" />
+        <result column="qcresult_info_id" property="qcresultInfoId" />
         <result column="cases_id" property="casesId" />
         <result column="score_res" property="scoreRes" />
         <result column="level" property="level" />

+ 1 - 0
src/main/resources/mapper/QcresultDetailMapper.xml

@@ -7,6 +7,7 @@
         <id column="id" property="id" />
         <result column="hospital_id" property="hospitalId" />
         <result column="behospital_code" property="behospitalCode" />
+        <result column="qcresult_info_id" property="qcresultInfoId" />
         <result column="cases_id" property="casesId" />
         <result column="cases_score" property="casesScore" />
         <result column="cases_entry_id" property="casesEntryId" />