Sfoglia il codice sorgente

Merge remote-tracking branch 'origin/master'

huey 1 anno fa
parent
commit
0658f62345

+ 17 - 12
src/main/java/com/dragon/tj/portal/auth/config/WebSecurityConfig.java

@@ -1,10 +1,6 @@
 package com.dragon.tj.portal.auth.config;
 
-import com.dragon.tj.portal.auth.service.JwtTokenAuthenticationFilter;
-import com.dragon.tj.portal.auth.service.MyCasAuthenticationEntryPoint;
-import com.dragon.tj.portal.auth.service.MySimpleUrlAuthenticationSuccessHandler;
-import com.dragon.tj.portal.auth.service.MyUserDetailsByNameServiceWrapper;
-import com.dragon.tj.portal.auth.service.MyUserDetailsService;
+import com.dragon.tj.portal.auth.service.*;
 import org.jasig.cas.client.validation.Cas20ServiceTicketValidator;
 import org.jasig.cas.client.validation.TicketValidator;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -34,6 +30,9 @@ public class WebSecurityConfig {
     @Value("${cas.login.url}")
     private String casLoginUrl;
 
+    @Value("${app.logout.url}")
+    private String appLogoutUrl;
+
     @Value("${cas.service.url}")
     private String casServiceUrl;
 
@@ -55,6 +54,8 @@ public class WebSecurityConfig {
     private MyUserDetailsService userDetailsService;
     @Autowired
     private MySimpleUrlAuthenticationSuccessHandler mySimpleUrlAuthenticationSuccessHandler;
+    @Autowired
+    private JwtTokenLogoutSuccessHandler logoutSuccessHandler;
 
     private static StringBuilder whiteList = new StringBuilder();
     private static String whiteListSplit = ",";
@@ -65,8 +66,6 @@ public class WebSecurityConfig {
      */
     static {
         whiteList.append("/test/login" + whiteListSplit);
-        whiteList.append("/subscribe/*" + whiteListSplit);
-        whiteList.append("/test/test1" + whiteListSplit);
         whiteList.append("/file/**" + whiteListSplit);
     }
 
@@ -94,11 +93,10 @@ public class WebSecurityConfig {
                 .exceptionHandling(exceptions -> exceptions.authenticationEntryPoint(authenticationEntryPoint()))
                 .addFilter(casAuthenticationFilter())
                 .addFilterBefore(jwtTokenAuthenticationFilter, CasAuthenticationFilter.class)
-                // .addFilterBefore(casLogoutFilter(), LogoutFilter.class)
-                // .addFilterBefore(singleSignOutFilter(), CasAuthenticationFilter.class);
-                // .addFilterBefore(new SingleSignOutFilter(), CasAuthenticationFilter.class)
-                .logout();
-
+                // .addFilterBefore(singleSignOutFilter(), CasAuthenticationFilter.class)
+                .logout()
+                .logoutUrl(appLogoutUrl)
+                .logoutSuccessHandler(logoutSuccessHandler);
         return http.build();
     }
 
@@ -142,4 +140,11 @@ public class WebSecurityConfig {
         return new Cas20ServiceTicketValidator(this.casBaseUrl);
     }
 
+//    @Bean
+//    public SingleSignOutFilter singleSignOutFilter() {
+//        SingleSignOutFilter singleSignOutFilter = new SingleSignOutFilter();
+//        singleSignOutFilter.setIgnoreInitConfiguration(true);
+//        return singleSignOutFilter;
+//    }
+
 }

+ 20 - 13
src/main/java/com/dragon/tj/portal/auth/controller/SsoController.java

@@ -3,20 +3,22 @@ package com.dragon.tj.portal.auth.controller;
 import com.dragon.tj.portal.auth.model.LoginUser;
 import com.dragon.tj.portal.auth.service.TokenService;
 import com.dragon.tj.portal.auth.web.entity.SysUser;
+import com.dragon.tj.portal.auth.web.service.SysUserService;
 import com.dragon.tj.portal.common.base.R;
 import com.dragon.tj.portal.common.enums.message.MessageInfoErrorEnums;
 import com.dragon.tj.portal.component.exception.message.MessageInfoException;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
-import javax.servlet.http.HttpServletResponse;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
+import javax.servlet.http.HttpServletRequest;
+import java.util.*;
 
 /**
  * <p>
@@ -32,16 +34,21 @@ public class SsoController {
 
     @Autowired
     private TokenService tokenService;
+    @Autowired
+    private SysUserService sysUserService;
+
 
     @GetMapping("/login")
-    public R login(HttpServletResponse response) {
-        SysUser sysUser = new SysUser();
-        sysUser.setIdcard("120222197001010002");
-        sysUser.setName("李四");
-        sysUser.setOrgCode("120000450200");
-        sysUser.setOrgName("服务实战值班岛");
-        List<String> perms = Arrays.asList("gzt", "yyzx");
+    public R login(@RequestParam(required = false) String idCard, HttpServletRequest request) {
+        if (StringUtils.isBlank(idCard)) {
+            idCard = "120222197001010002";
+        }
+        SysUser sysUser = sysUserService.getUserById(idCard);
+        List<String> perms = Arrays.asList("gzt", "yyzx", "ywzx", "xxgl", "rjxz", "rzcx", "cjwt");
         LoginUser loginUser = new LoginUser(sysUser.getIdcard(), sysUser.getOrgCode(), sysUser, new HashSet<>(perms));
+        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
+        authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
+        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
         String token = tokenService.createToken(loginUser);
         Map<String, String> data = new HashMap<>();
         data.put("token", token);

+ 59 - 13
src/main/java/com/dragon/tj/portal/auth/controller/UserController.java

@@ -1,43 +1,89 @@
 package com.dragon.tj.portal.auth.controller;
 
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.dragon.tj.portal.auth.model.LoginUser;
+import com.dragon.tj.portal.auth.service.TokenService;
 import com.dragon.tj.portal.auth.util.SecurityUtils;
 import com.dragon.tj.portal.auth.web.entity.SysUser;
 import com.dragon.tj.portal.auth.web.service.SysUserService;
 import com.dragon.tj.portal.common.base.R;
+import com.dragon.tj.portal.common.constants.DateTimeFormatterConstant;
+import com.dragon.tj.portal.common.enums.log.ModuleEnum;
+import com.dragon.tj.portal.component.redis.StringCacheUtil;
 import com.dragon.tj.portal.entity.PageParam;
+import com.dragon.tj.portal.entity.SysLog;
+import com.dragon.tj.portal.service.SysLogService;
 import com.dragonsoft.encrypt.EncryptFactory;
 import com.dragonsoft.encrypt.EncryptHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
 
 @RestController
 @RequestMapping("/user")
 public class UserController {
+    private static final Logger LOGGER = LoggerFactory.getLogger(UserController.class);
+
+    @Value("${external.esou.url}")
+    private String esouUrl;
+    @Value("${external.dcuc.url}")
+    private String dcucUrl;
+
 
     @Autowired
     private SysUserService sysUserService;
+    @Autowired
+    private SysLogService sysLogService;
+    @Autowired
+    private StringCacheUtil stringCacheUtil;
 
     @GetMapping("/info")
     public R<Map<String, Object>> info(HttpServletRequest request) {
         LoginUser loginUser = SecurityUtils.getLoginUser();
-        Map<String, Object> data = new HashMap<>(3);
-        data.put("name", loginUser.getUsername());
-        data.put("deptCode", loginUser.getOrgCode());
-        data.put("deptName", loginUser.getUser().getOrgName());
-        data.put("idCard", loginUser.getIdCard());
+
+        Map<String, String> userInfo = new HashMap<>();
+        userInfo.put("name", loginUser.getUsername());
+        userInfo.put("deptCode", loginUser.getOrgCode());
+        userInfo.put("deptName", loginUser.getUser().getOrgName());
+        userInfo.put("idCard", loginUser.getIdCard());
+
+        try {
+            // 获取当前在线人数
+            Set<String> keys = stringCacheUtil.keys(TokenService.LOGIN_TOKEN_KEY + "*");
+            userInfo.put("loginUserNum", String.valueOf(keys.size()));
+
+            // 获取上次登录信息
+            List<SysLog> sysLogs = sysLogService.list(
+                    Wrappers.<SysLog>query().lambda()
+                            .eq(SysLog::getCreateBy, loginUser.getIdCard())
+                            .eq(SysLog::getModuleType, ModuleEnum.LOGIN.getCode())
+                            .orderByDesc(SysLog::getCreateTime)
+                            .last("LIMIT 2")
+            );
+            if (Objects.nonNull(sysLogs) && sysLogs.size() == 2) {
+                userInfo.put("lastLoginTime", DateTimeFormatterConstant.FORMATTER0.format(sysLogs.get(1).getCreateTime()));
+                userInfo.put("lastLoginIp", sysLogs.get(1).getRemoteAddr());
+            }
+        } catch (Exception e) {
+            LOGGER.error("获取用户[{}]上次登录信息失败", loginUser.getIdCard(), e);
+        }
+
+        Map<String, String> links = new HashMap<>();
         EncryptHandler encryptHandler = EncryptFactory.getInstance();
-        data.put("encryptIdCard", encryptHandler.encapsulateString(loginUser.getIdCard()));
+        String encryptIdCard = encryptHandler.encapsulateString(loginUser.getIdCard());
+        links.put("esouUrl", esouUrl.replace("{USER_IDCARD}", encryptIdCard));
+        links.put("dcucUrl", dcucUrl);
+
+        Map<String, Object> data = new HashMap<>(2);
         data.put("roles", loginUser.getPermissions());
+        data.put("userInfo", userInfo);
+        data.put("links", links);
         return R.ok(data);
     }
 

+ 51 - 0
src/main/java/com/dragon/tj/portal/auth/service/JwtTokenLogoutSuccessHandler.java

@@ -0,0 +1,51 @@
+package com.dragon.tj.portal.auth.service;
+
+import cn.hutool.json.JSONUtil;
+import com.dragon.tj.portal.auth.model.LoginUser;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.MediaType;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+@Configuration
+public class JwtTokenLogoutSuccessHandler implements LogoutSuccessHandler {
+
+    @Autowired
+    private TokenService tokenService;
+
+    @Value("${cas.logout.url}")
+    private String casLogoutUrl;
+
+    @Value("${app.home.url}")
+    private String appHomeUrl;
+
+    /**
+     * 退出处理
+     */
+    @Override
+    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
+            throws IOException, ServletException {
+        LoginUser loginUser = tokenService.getLoginUser(request);
+        if (Objects.nonNull(loginUser)) {
+            // 删除redis记录
+            tokenService.delLoginUser(loginUser.getToken());
+        }
+        Map<String, String> data = new HashMap<>();
+        data.put("casLogoutUrl", casLogoutUrl + "?service=" + URLEncoder.encode(appHomeUrl, StandardCharsets.UTF_8.name()));
+        response.setStatus(HttpServletResponse.SC_OK);
+        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
+        response.getWriter().write(JSONUtil.toJsonStr(data));
+    }
+}

+ 13 - 0
src/main/java/com/dragon/tj/portal/auth/service/TokenService.java

@@ -3,6 +3,8 @@ package com.dragon.tj.portal.auth.service;
 import cn.hutool.core.util.IdUtil;
 import cn.hutool.json.JSONUtil;
 import com.dragon.tj.portal.auth.model.LoginUser;
+import com.dragon.tj.portal.common.enums.log.ModuleEnum;
+import com.dragon.tj.portal.component.log.annotation.SysLog;
 import com.dragon.tj.portal.component.redis.StringCacheUtil;
 import io.jsonwebtoken.Claims;
 import io.jsonwebtoken.Jwts;
@@ -71,6 +73,16 @@ public class TokenService {
         return null;
     }
 
+    /**
+     * 删除用户身份信息
+     */
+    public void delLoginUser(String token) {
+        if (StringUtils.isNotEmpty(token)) {
+            String userKey = getTokenKey(token);
+            stringCacheUtil.del(userKey);
+        }
+    }
+
     /**
      * 从令牌中获取数据声明
      *
@@ -90,6 +102,7 @@ public class TokenService {
      * @param loginUser 用户信息
      * @return 令牌
      */
+    @SysLog(value = "登录", module = ModuleEnum.LOGIN)
     public String createToken(LoginUser loginUser) {
         String token = IdUtil.fastUUID();
         LOGGER.info("token info: [{}]: [{}]", loginUser.getIdCard(), token);

+ 3 - 1
src/main/java/com/dragon/tj/portal/common/enums/log/ModuleEnum.java

@@ -38,7 +38,9 @@ public enum ModuleEnum {
     ISSUE_DELETE("6002", "问题删除"),
     ISSUE_UPDATE("6003", "问题添加"),
     ISSUE_QUERY("6004", "问题查询"),
-    ;
+
+    LOGIN("9999", "登录"),
+    LOGOUT("9998", "退出登录");
 
     private final String code;
     private final String desc;

+ 2 - 1
src/main/java/com/dragon/tj/portal/component/log/aspect/SysLogAspect.java

@@ -22,6 +22,7 @@ package com.dragon.tj.portal.component.log.aspect;
 import com.alibaba.fastjson.JSON;
 import com.dragon.tj.portal.auth.model.LoginUser;
 import com.dragon.tj.portal.auth.service.TokenService;
+import com.dragon.tj.portal.auth.util.SecurityUtils;
 import com.dragon.tj.portal.component.log.annotation.SysLog;
 import com.dragon.tj.portal.component.log.dto.SysLogDTO;
 import com.dragon.tj.portal.component.log.event.SysLogEvent;
@@ -75,7 +76,7 @@ public class SysLogAspect {
         log.debug("[类名]:{},[方法]:{}", strClassName, strMethodName);
 
         HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
-        LoginUser loginUser = tokenService.getLoginUser(request);
+        LoginUser loginUser = SecurityUtils.getLoginUser();
         String createBy = "admin";
         String createUser = "admin";
         if (Objects.nonNull(loginUser)) {

+ 2 - 1
src/main/java/com/dragon/tj/portal/component/message/MessageConsumer.java

@@ -3,6 +3,7 @@ package com.dragon.tj.portal.component.message;
 import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
+import com.dragon.tj.portal.common.constants.BusinessConstants;
 import com.dragon.tj.portal.common.convert.mesage.MessageReqConvert;
 import com.dragon.tj.portal.common.convert.notice.NoticeReqConvert;
 import com.dragon.tj.portal.common.dto.message.MessageInfoSend;
@@ -83,7 +84,7 @@ public class MessageConsumer {
         ack.acknowledge();
     }
 
-    @KafkaListener(topicPattern = "sseTopic.*")
+    @KafkaListener(topicPattern = BusinessConstants.TOPIC_PRE + ".*")
     public void sseConnectionProcess2(String msg, Acknowledgment ack) {
         log.info("get kafka2 msg from topic:{}, msg:{}", KafkaInitialConfiguration.sseTopic, msg);
         if (StrUtil.isEmpty(msg)) {

+ 0 - 3
src/main/java/com/dragon/tj/portal/component/redis/StringCacheUtil.java

@@ -1,12 +1,9 @@
 package com.dragon.tj.portal.component.redis;
 
-import lombok.NoArgsConstructor;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.MapUtils;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.HashOperations;
 import org.springframework.data.redis.core.StringRedisTemplate;
-import org.springframework.stereotype.Component;
 
 import java.time.Duration;
 import java.util.*;

+ 6 - 0
src/main/java/com/dragon/tj/portal/entity/AppInfo.java

@@ -137,4 +137,10 @@ public class AppInfo implements Serializable {
      * */
     @TableField(exist = false)
     private Integer isSpecial;
+
+    /**
+     * 用户是否收藏
+     */
+    @TableField(exist = false)
+    private Integer isStar;
 }

+ 6 - 0
src/main/java/com/dragon/tj/portal/entity/BusinessInfo.java

@@ -114,4 +114,10 @@ public class BusinessInfo {
      */
     @TableField(exist = false)
     private int seq;
+
+    /**
+     * 用户是否收藏
+     */
+    @TableField(exist = false)
+    private Integer isStar;
 }

+ 34 - 0
src/main/java/com/dragon/tj/portal/service/impl/AppServiceImpl.java

@@ -138,9 +138,41 @@ public class AppServiceImpl implements AppService {
 
         rowPage.addOrder(OrderItem.desc(appInfoPage.getOrder()));
 
+        if (appInfo.getIsStar() != null && appInfo.getIsStar() == 1) {
+            Page<AppInfo> appInfoPage1 = appInfoMapper.selectPage(rowPage, queryWrapper);
+
+            return checkFavorites(appInfoPage1);
+        }
+
         return appInfoMapper.selectPage(rowPage, queryWrapper);
     }
 
+    /*
+    * 热门应用是否收藏
+    * */
+    private Page<AppInfo> checkFavorites(Page<AppInfo> appInfoPage){
+        List<AppInfo> records = appInfoPage.getRecords();
+        List<Long> ids = records.stream().map(AppInfo::getId).collect(Collectors.toList());
+        if (ids.size() == 0){
+            return appInfoPage;
+        }
+        LambdaQueryWrapper<InstallInfo> wrapper = new LambdaQueryWrapper<>();
+        wrapper.select(InstallInfo::getAppId);
+        wrapper.eq(InstallInfo::getBusinessId,0);
+        wrapper.eq(SecurityUtils.getLoginUser() != null,
+                InstallInfo::getUserIdcard,SecurityUtils.getLoginUser().getIdCard());
+        wrapper.in(InstallInfo::getAppId,ids);
+        List<InstallInfo> installInfos = installInfoMapper.selectList(wrapper);
+
+        Map<Integer, List<InstallInfo>> collect = installInfos.stream()
+                .collect(Collectors.groupingBy(InstallInfo::getAppId));
+        //
+        for (AppInfo info : records) {
+            info.setIsStar(collect.get(info.getId().intValue()) != null ? 1: 0);
+        }
+
+        return appInfoPage;
+    }
 
     /*
      * 安装应用
@@ -150,6 +182,8 @@ public class AppServiceImpl implements AppService {
 
         //是否已安装
         QueryWrapper<InstallInfo> wrapper = new QueryWrapper<>();
+        wrapper.eq("del_flag", 0);
+        wrapper.eq("business_id", 0);
         wrapper.eq("app_id", appId);
         wrapper.eq("user_idcard", userIdcard);
         InstallInfo installed = installInfoMapper.selectOne(wrapper);

+ 35 - 0
src/main/java/com/dragon/tj/portal/service/impl/BusinessServiceImpl.java

@@ -28,6 +28,7 @@ import java.time.LocalDateTime;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 @Service
 public class BusinessServiceImpl implements BusinessService {
@@ -133,9 +134,42 @@ public class BusinessServiceImpl implements BusinessService {
 
         rowPage.addOrder(OrderItem.desc(businessInfoPage.getOrder()));
 
+        if (businessInfo.getIsStar() != null && businessInfo.getIsStar() == 1){
+            Page<BusinessInfo> businessInfoPage1 = businessMapper.selectPage(rowPage, queryWrapper);
+
+            return checkFavorites(businessInfoPage1);
+        }
+
         return businessMapper.selectPage(rowPage, queryWrapper);
     }
 
+    /*
+     * 热门应用是否收藏
+     * */
+    private Page<BusinessInfo> checkFavorites(Page<BusinessInfo> businessInfoPage){
+        List<BusinessInfo> records = businessInfoPage.getRecords();
+        List<Long> ids = records.stream().map(BusinessInfo::getId).collect(Collectors.toList());
+        if (ids.size() == 0){
+            return businessInfoPage;
+        }
+        LambdaQueryWrapper<InstallInfo> wrapper = new LambdaQueryWrapper<>();
+        wrapper.select(InstallInfo::getBusinessId);
+        wrapper.ne(InstallInfo::getBusinessId,0);
+        wrapper.eq(SecurityUtils.getLoginUser() != null,
+                InstallInfo::getUserIdcard,SecurityUtils.getLoginUser().getIdCard());
+        wrapper.in(InstallInfo::getBusinessId,ids);
+        List<InstallInfo> installInfos = installInfoMapper.selectList(wrapper);
+
+        Map<Integer, List<InstallInfo>> collect = installInfos.stream()
+                .collect(Collectors.groupingBy(InstallInfo::getBusinessId));
+
+        for (BusinessInfo info : records) {
+            info.setIsStar(collect.get(info.getId().intValue()) != null ? 1: 0);
+        }
+
+        return businessInfoPage;
+    }
+
 
     /*
      * 安装业务
@@ -157,6 +191,7 @@ public class BusinessServiceImpl implements BusinessService {
 
         //是否已安装
         QueryWrapper<InstallInfo> wrapper2 = new QueryWrapper<>();
+        wrapper2.eq("del_flag", 0);
         wrapper2.eq("app_id", appId);
         wrapper2.eq("business_id", businessId);
         wrapper2.eq("user_idcard", userIdcard);

+ 6 - 0
src/main/resources/application-dev.properties

@@ -34,6 +34,12 @@ cas.service.url=http://localhost:8081/api/sso/login
 cas.filter.url=/sso/login
 cas.target.url=http://localhost:8081/#/auth-redirect?token=
 cas.failure.url=http://localhost:8081/#/401
+app.logout.url=/user/logout
+app.home.url=http://localhost:8081
+
+########## external link ###########
+external.dcuc.url=http://localhost:8084
+external.esou.url=http://localhost:8084/?idcard={USER_IDCARD}&query={QUERY}
 
 ########## dcuc api ################
 client.log.enabled=true

+ 7 - 1
src/main/resources/application-local.properties

@@ -5,7 +5,7 @@ spring.datasource.password=portal01!
 mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
 #log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl
 ###########kafka#############
-#指定哪些appId能发topic,动态变更后,不能自动订阅需重启服务
+#\u6307\u5B9A\u54EA\u4E9BappId\u80FD\u53D1topic\uFF0C\u52A8\u6001\u53D8\u66F4\u540E,\u4E0D\u80FD\u81EA\u52A8\u8BA2\u9605\u9700\u91CD\u542F\u670D\u52A1
 kafka.topics=sseTopic-a1,sseTopic-a2
 spring.kafka.bootstrap-servers=149.28.158.127:9092
 spring.kafka.producer.retries=2
@@ -31,6 +31,12 @@ cas.service.url=http://localhost:8081/api/sso/login
 cas.target.url=http://localhost:8081/#/?token=
 cas.filter.url=/sso/login
 cas.failure.url=http://localhost:8081/#/401
+app.logout.url=/user/logout
+app.home.url=http://localhost:8081
+
+########## external link ###########
+external.dcuc.url=http://localhost:8084
+external.esou.url=http://localhost:8084/?idcard=${USER_IDCARD}&query=${QUERY}
 
 ########## dcuc api ################
 client.dcuc.user.url=http://localhost:8086/dcuc/user/api/

+ 6 - 0
src/main/resources/application-prod.properties

@@ -35,6 +35,12 @@ cas.service.url=http://localhost:8081/api/sso/login
 cas.filter.url=/sso/login
 cas.target.url=http://localhost:8081/#/auth-redirect?token=
 cas.failure.url=http://localhost:8081/#/401
+app.logout.url=/user/logout
+app.home.url=http://localhost:8081
+
+########## external link ###########
+external.dcuc.url=http://localhost:8084
+external.esou.url=http://localhost:8084/?idcard=${USER_IDCARD}&query=${QUERY}
 
 ########## dcuc api ################
 client.dcuc.user.url=http://17.22.60.108:8870/dcuc/api/