mirror of
https://gitee.com/hhyykk/ipms-sjy.git
synced 2025-08-14 10:11:53 +08:00
Merge remote-tracking branch 'origin/develop' into develop
# Conflicts: # yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/article/AppArticleController.java
This commit is contained in:
@@ -15,6 +15,7 @@ import java.util.Arrays;
|
||||
@Getter
|
||||
public enum TerminalEnum implements IntArrayValuable {
|
||||
|
||||
UNKNOWN(0, "未知"), // 目的:在无法解析到 terminal 时,使用它
|
||||
WECHAT_MINI_PROGRAM(10, "微信小程序"),
|
||||
WECHAT_WAP(11, "微信公众号"),
|
||||
H5(20, "H5 网页"),
|
||||
|
@@ -1,10 +1,12 @@
|
||||
package cn.iocoder.yudao.framework.common.util.cache;
|
||||
|
||||
import com.alibaba.ttl.threadpool.TtlExecutors;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
@@ -15,11 +17,13 @@ import java.util.concurrent.Executors;
|
||||
public class CacheUtils {
|
||||
|
||||
public static <K, V> LoadingCache<K, V> buildAsyncReloadingCache(Duration duration, CacheLoader<K, V> loader) {
|
||||
Executor executor = Executors.newCachedThreadPool( // TODO 芋艿:可能要思考下,未来要不要做成可配置
|
||||
TtlExecutors.getDefaultDisableInheritableThreadFactory()); // TTL 保证 ThreadLocal 可以透传
|
||||
return CacheBuilder.newBuilder()
|
||||
// 只阻塞当前数据加载线程,其他线程返回旧值
|
||||
.refreshAfterWrite(duration)
|
||||
// 通过 asyncReloading 实现全异步加载,包括 refreshAfterWrite 被阻塞的加载线程
|
||||
.build(CacheLoader.asyncReloading(loader, Executors.newCachedThreadPool())); // TODO 芋艿:可能要思考下,未来要不要做成可配置
|
||||
.build(CacheLoader.asyncReloading(loader, executor));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -88,8 +88,6 @@ public class ServletUtils {
|
||||
return JakartaServletUtil.getClientIP(request);
|
||||
}
|
||||
|
||||
// TODO @疯狂:terminal 还是从 ServletUtils 里拿,更容易全局治理;
|
||||
|
||||
public static boolean isJsonRequest(ServletRequest request) {
|
||||
return StrUtil.startWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE);
|
||||
}
|
||||
|
@@ -490,6 +490,37 @@ id,name,type,parentId
|
||||
441700,阳江市,3,440000
|
||||
441800,清远市,3,440000
|
||||
441900,东莞市,3,440000
|
||||
441901,莞城区,4,441900
|
||||
441902,南城区,4,441900
|
||||
441904,万江区,4,441900
|
||||
441905,石碣镇,4,441900
|
||||
441906,石龙镇,4,441900
|
||||
441907,茶山镇,4,441900
|
||||
441908,石排镇,4,441900
|
||||
441909,企石镇,4,441900
|
||||
441910,横沥镇,4,441900
|
||||
441911,桥头镇,4,441900
|
||||
441912,谢岗镇,4,441900
|
||||
441913,东坑镇,4,441900
|
||||
441914,常平镇,4,441900
|
||||
441915,寮步镇,4,441900
|
||||
441916,大朗镇,4,441900
|
||||
441917,麻涌镇,4,441900
|
||||
441918,中堂镇,4,441900
|
||||
441919,高埗镇,4,441900
|
||||
441920,樟木头镇,4,441900
|
||||
441921,大岭山镇,4,441900
|
||||
441922,望牛墩镇,4,441900
|
||||
441923,黄江镇,4,441900
|
||||
441924,洪梅镇,4,441900
|
||||
441925,清溪镇,4,441900
|
||||
441926,沙田镇,4,441900
|
||||
441927,道滘镇,4,441900
|
||||
441928,塘厦镇,4,441900
|
||||
441929,虎门镇,4,441900
|
||||
441930,厚街镇,4,441900
|
||||
441931,凤岗镇,4,441900
|
||||
441932,长安镇,4,441900
|
||||
442000,中山市,3,440000
|
||||
445100,潮州市,3,440000
|
||||
445200,揭阳市,3,440000
|
||||
@@ -3605,4 +3636,4 @@ id,name,type,parentId
|
||||
659008,可克达拉市,4,659000
|
||||
659009,昆玉市,4,659000
|
||||
659010,胡杨河市,4,659000
|
||||
659011,新星市,4,659000
|
||||
659011,新星市,4,659000
|
|
@@ -46,6 +46,7 @@
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
@@ -71,6 +71,7 @@ public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientC
|
||||
if (StrUtil.isNotEmpty(config.getPrivateCertContent())) {
|
||||
payConfig.setPrivateCertPath(FileUtils.createTempFile(config.getPrivateCertContent()).getPath());
|
||||
}
|
||||
// payConfig.setCertSerialNo();
|
||||
|
||||
// 创建 client 客户端
|
||||
client = new WxPayServiceImpl();
|
||||
|
@@ -41,6 +41,7 @@ public abstract class AbstractSmsClient implements SmsClient {
|
||||
return;
|
||||
}
|
||||
log.info("[refresh][配置({})发生变化,重新初始化]", properties);
|
||||
this.properties = properties;
|
||||
// 初始化
|
||||
this.init();
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
package cn.iocoder.yudao.framework.tenant.core.context;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.DocumentEnum;
|
||||
import com.alibaba.ttl.TransmittableThreadLocal;
|
||||
|
||||
@@ -21,7 +22,7 @@ public class TenantContextHolder {
|
||||
private static final ThreadLocal<Boolean> IGNORE = new TransmittableThreadLocal<>();
|
||||
|
||||
/**
|
||||
* 获得租户编号。
|
||||
* 获得租户编号
|
||||
*
|
||||
* @return 租户编号
|
||||
*/
|
||||
@@ -29,6 +30,16 @@ public class TenantContextHolder {
|
||||
return TENANT_ID.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得租户编号 String
|
||||
*
|
||||
* @return 租户编号
|
||||
*/
|
||||
public static String getTenantIdStr() {
|
||||
Long tenantId = getTenantId();
|
||||
return StrUtil.toStringOrNull(tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得租户编号。如果不存在,则抛出 NullPointerException 异常
|
||||
*
|
||||
|
@@ -1,12 +1,14 @@
|
||||
package cn.iocoder.yudao.framework.excel.core.util;
|
||||
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.alibaba.excel.converters.longconverter.LongStringConverter;
|
||||
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -33,9 +35,10 @@ public class ExcelUtils {
|
||||
EasyExcel.write(response.getOutputStream(), head)
|
||||
.autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理
|
||||
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 基于 column 长度,自动适配。最大 255 宽度
|
||||
.registerConverter(new LongStringConverter()) // 避免 Long 类型丢失精度
|
||||
.sheet(sheetName).doWrite(data);
|
||||
// 设置 header 和 contentType。写在最后的原因是,避免报错时,响应 contentType 已经被修改了
|
||||
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
|
||||
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, StandardCharsets.UTF_8));
|
||||
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
|
||||
}
|
||||
|
||||
|
@@ -81,7 +81,7 @@ public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {
|
||||
}
|
||||
// 腾讯云必须有 region,否则会报错
|
||||
if (config.getEndpoint().contains(ENDPOINT_TENCENT)) {
|
||||
return StrUtil.subAfter(config.getEndpoint(), ".cos.", false)
|
||||
return StrUtil.subAfter(config.getEndpoint(), "cos.", false)
|
||||
.replaceAll("." + ENDPOINT_TENCENT, ""); // 去除 Endpoint
|
||||
}
|
||||
return null;
|
||||
|
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.framework.flowable.config;
|
||||
import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
|
||||
import cn.iocoder.yudao.framework.flowable.core.web.FlowableWebFilter;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.core.task.AsyncListenableTaskExecutor;
|
||||
@@ -17,6 +18,7 @@ public class YudaoFlowableConfiguration {
|
||||
* 如果不创建,会导致项目启动时,Flowable 报错的问题
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public AsyncListenableTaskExecutor taskExecutor() {
|
||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
executor.setCorePoolSize(8);
|
||||
@@ -40,4 +42,5 @@ public class YudaoFlowableConfiguration {
|
||||
registrationBean.setOrder(WebFilterOrderEnum.FLOWABLE_FILTER);
|
||||
return registrationBean;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -65,6 +65,12 @@
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>dynamic-datasource-spring-boot3-starter</artifactId> <!-- 多数据源 -->
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-undertow</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
@@ -146,8 +146,8 @@ public interface BaseMapperX<T> extends MPJBaseMapper<T> {
|
||||
*
|
||||
* @param entities 实体们
|
||||
*/
|
||||
default void insertBatch(Collection<T> entities) {
|
||||
Db.saveBatch(entities);
|
||||
default Boolean insertBatch(Collection<T> entities) {
|
||||
return Db.saveBatch(entities);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,28 +156,28 @@ public interface BaseMapperX<T> extends MPJBaseMapper<T> {
|
||||
* @param entities 实体们
|
||||
* @param size 插入数量 Db.saveBatch 默认为 1000
|
||||
*/
|
||||
default void insertBatch(Collection<T> entities, int size) {
|
||||
Db.saveBatch(entities, size);
|
||||
default Boolean insertBatch(Collection<T> entities, int size) {
|
||||
return Db.saveBatch(entities, size);
|
||||
}
|
||||
|
||||
default void updateBatch(T update) {
|
||||
update(update, new QueryWrapper<>());
|
||||
default int updateBatch(T update) {
|
||||
return update(update, new QueryWrapper<>());
|
||||
}
|
||||
|
||||
default void updateBatch(Collection<T> entities) {
|
||||
Db.updateBatchById(entities);
|
||||
default Boolean updateBatch(Collection<T> entities) {
|
||||
return Db.updateBatchById(entities);
|
||||
}
|
||||
|
||||
default void updateBatch(Collection<T> entities, int size) {
|
||||
Db.updateBatchById(entities, size);
|
||||
default Boolean updateBatch(Collection<T> entities, int size) {
|
||||
return Db.updateBatchById(entities, size);
|
||||
}
|
||||
|
||||
default void insertOrUpdate(T entity) {
|
||||
Db.saveOrUpdate(entity);
|
||||
default Boolean insertOrUpdate(T entity) {
|
||||
return Db.saveOrUpdate(entity);
|
||||
}
|
||||
|
||||
default void insertOrUpdateBatch(Collection<T> collection) {
|
||||
Db.saveOrUpdateBatch(collection);
|
||||
default Boolean insertOrUpdateBatch(Collection<T> collection) {
|
||||
return Db.saveOrUpdateBatch(collection);
|
||||
}
|
||||
|
||||
default int delete(String field, String value) {
|
||||
|
@@ -12,7 +12,10 @@
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
<description>用户的认证、权限的校验</description>
|
||||
<description>
|
||||
1. security:用户的认证、权限的校验,实现「谁」可以做「什么事」
|
||||
2. operatelog:操作日志,实现「谁」在「什么时间」对「什么」做了「什么事」
|
||||
</description>
|
||||
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
||||
|
||||
<dependencies>
|
||||
@@ -50,6 +53,13 @@
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<!-- Spring Boot 通用操作日志组件,基于注解实现 -->
|
||||
<!-- 此组件解决的问题是:「谁」在「什么时间」对「什么」做了「什么事」 -->
|
||||
<groupId>io.github.mouzt</groupId>
|
||||
<artifactId>bizlog-sdk</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 业务组件 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
|
@@ -0,0 +1,27 @@
|
||||
package cn.iocoder.yudao.framework.operatelog.config;
|
||||
|
||||
import cn.iocoder.yudao.framework.operatelog.core.service.ILogRecordServiceImpl;
|
||||
import com.mzt.logapi.service.ILogRecordService;
|
||||
import com.mzt.logapi.starter.annotation.EnableLogRecord;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
|
||||
/**
|
||||
* 操作日志配置类
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@EnableLogRecord(tenant = "") // 貌似用不上 tenant 这玩意给个空好啦
|
||||
@AutoConfiguration
|
||||
@Slf4j
|
||||
public class YudaoOperateLogV2Configuration {
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
public ILogRecordService iLogRecordServiceImpl() {
|
||||
return new ILogRecordServiceImpl();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* 占位,无特殊作用
|
||||
*/
|
||||
package cn.iocoder.yudao.framework.operatelog.core;
|
@@ -0,0 +1,85 @@
|
||||
package cn.iocoder.yudao.framework.operatelog.core.service;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
|
||||
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
|
||||
import cn.iocoder.yudao.module.system.api.logger.OperateLogApi;
|
||||
import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2CreateReqDTO;
|
||||
import com.mzt.logapi.beans.LogRecord;
|
||||
import com.mzt.logapi.service.ILogRecordService;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
// TODO @puhui999:LogRecordServiceImpl 改成这个名字哈
|
||||
/**
|
||||
* 操作日志 ILogRecordService 实现类
|
||||
*
|
||||
* 基于 {@link OperateLogApi} 实现,记录操作日志
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Slf4j
|
||||
public class ILogRecordServiceImpl implements ILogRecordService {
|
||||
|
||||
@Resource
|
||||
private OperateLogApi operateLogApi;
|
||||
|
||||
@Override
|
||||
public void record(LogRecord logRecord) {
|
||||
// 1. 补全通用字段
|
||||
OperateLogV2CreateReqDTO reqDTO = new OperateLogV2CreateReqDTO();
|
||||
reqDTO.setTraceId(TracerUtils.getTraceId());
|
||||
// 补充用户信息
|
||||
fillUserFields(reqDTO);
|
||||
// 补全模块信息
|
||||
fillModuleFields(reqDTO, logRecord);
|
||||
// 补全请求信息
|
||||
fillRequestFields(reqDTO);
|
||||
|
||||
// 2. 异步记录日志
|
||||
operateLogApi.createOperateLogV2(reqDTO);
|
||||
// TODO 测试结束删除或搞个开关
|
||||
log.info("操作日志 ===> {}", reqDTO);
|
||||
}
|
||||
|
||||
private static void fillUserFields(OperateLogV2CreateReqDTO reqDTO) {
|
||||
// TODO @puhui999:使用 SecurityFrameworkUtils。因为要考虑,rpc、mq、job,它其实不是 web;
|
||||
reqDTO.setUserId(WebFrameworkUtils.getLoginUserId());
|
||||
reqDTO.setUserType(WebFrameworkUtils.getLoginUserType());
|
||||
}
|
||||
|
||||
public static void fillModuleFields(OperateLogV2CreateReqDTO reqDTO, LogRecord logRecord) {
|
||||
reqDTO.setType(logRecord.getType()); // 大模块类型,例如:CRM 客户
|
||||
reqDTO.setSubType(logRecord.getSubType());// 操作名称,例如:转移客户
|
||||
reqDTO.setBizId(Long.parseLong(logRecord.getBizNo())); // 业务编号,例如:客户编号
|
||||
reqDTO.setAction(logRecord.getAction());// 操作内容,例如:修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。
|
||||
reqDTO.setExtra(logRecord.getExtra()); // 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 ),例如说,记录订单编号,{ orderId: "1"}
|
||||
}
|
||||
|
||||
private static void fillRequestFields(OperateLogV2CreateReqDTO reqDTO) {
|
||||
// 获得 Request 对象
|
||||
HttpServletRequest request = ServletUtils.getRequest();
|
||||
if (request == null) {
|
||||
return;
|
||||
}
|
||||
// 补全请求信息
|
||||
reqDTO.setRequestMethod(request.getMethod());
|
||||
reqDTO.setRequestUrl(request.getRequestURI());
|
||||
reqDTO.setUserIp(ServletUtils.getClientIP(request));
|
||||
reqDTO.setUserAgent(ServletUtils.getUserAgent(request));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LogRecord> queryLog(String bizNo, String type) {
|
||||
throw new UnsupportedOperationException("使用 OperateLogApi 进行操作日志的查询");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LogRecord> queryLogByBizNo(String bizNo, String type, String subType) {
|
||||
throw new UnsupportedOperationException("使用 OperateLogApi 进行操作日志的查询");
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* 基于 mzt-log 框架
|
||||
* 实现操作日志功能
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
package cn.iocoder.yudao.framework.operatelog;
|
@@ -1,2 +1,3 @@
|
||||
cn.iocoder.yudao.framework.security.config.YudaoSecurityAutoConfiguration
|
||||
cn.iocoder.yudao.framework.security.config.YudaoWebSecurityConfigurerAdapter
|
||||
cn.iocoder.yudao.framework.security.config.YudaoWebSecurityConfigurerAdapter
|
||||
cn.iocoder.yudao.framework.operatelog.config.YudaoOperateLogV2Configuration
|
@@ -1,8 +1,11 @@
|
||||
package cn.iocoder.yudao.framework.web.core.util;
|
||||
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import cn.hutool.extra.servlet.ServletUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.TerminalEnum;
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
|
||||
import cn.iocoder.yudao.framework.web.config.WebProperties;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
@@ -25,6 +28,13 @@ public class WebFrameworkUtils {
|
||||
|
||||
public static final String HEADER_TENANT_ID = "tenant-id";
|
||||
|
||||
/**
|
||||
* 终端的 Header
|
||||
*
|
||||
* @see cn.iocoder.yudao.framework.common.enums.TerminalEnum
|
||||
*/
|
||||
public static final String HEADER_TERMINAL = "terminal";
|
||||
|
||||
private static WebProperties properties;
|
||||
|
||||
public WebFrameworkUtils(WebProperties webProperties) {
|
||||
@@ -107,6 +117,15 @@ public class WebFrameworkUtils {
|
||||
return getLoginUserId(request);
|
||||
}
|
||||
|
||||
public static Integer getTerminal() {
|
||||
HttpServletRequest request = getRequest();
|
||||
if (request == null) {
|
||||
return TerminalEnum.UNKNOWN.getTerminal();
|
||||
}
|
||||
String terminalValue = request.getHeader(HEADER_TERMINAL);
|
||||
return NumberUtil.parseInt(terminalValue, TerminalEnum.UNKNOWN.getTerminal());
|
||||
}
|
||||
|
||||
public static void setCommonResult(ServletRequest request, CommonResult<?> result) {
|
||||
request.setAttribute(REQUEST_ATTRIBUTE_COMMON_RESULT, result);
|
||||
}
|
||||
|
@@ -38,17 +38,6 @@
|
||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Web 相关 -->
|
||||
<dependency>
|
||||
<!-- 为什么是 websocket 依赖 security 呢?而不是 security 拓展 websocket 呢?
|
||||
因为 websocket 和 LoginUser 当前登录的用户有一定的相关性,具体可见 WebSocketSessionManagerImpl 逻辑。
|
||||
如果让 security 拓展 websocket 的话,会导致 websocket 组件的封装很散,进而增大理解成本。
|
||||
-->
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-security</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- 消息队列相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
|
@@ -66,7 +66,7 @@ public class WebSocketSessionManagerImpl implements WebSocketSessionManager {
|
||||
@Override
|
||||
public void removeSession(WebSocketSession session) {
|
||||
// 移除从 idSessions 中
|
||||
idSessions.remove(session.getId(), session);
|
||||
idSessions.remove(session.getId());
|
||||
// 移除从 idSessions 中
|
||||
LoginUser user = WebSocketFrameworkUtils.getLoginUser(session);
|
||||
if (user == null) {
|
||||
|
Reference in New Issue
Block a user