parent
e98b06e7fe
commit
60fa1c3bfc
@ -0,0 +1,76 @@
|
||||
/**
|
||||
* Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.opsli.core.cache.pushsub.handler;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.opsli.common.constants.CacheConstants;
|
||||
import org.opsli.core.cache.local.CacheUtil;
|
||||
import org.opsli.core.cache.pushsub.enums.MsgArgsType;
|
||||
import org.opsli.core.cache.pushsub.enums.PushSubType;
|
||||
import org.opsli.core.utils.MenuUtil;
|
||||
import org.opsli.core.utils.OrgUtil;
|
||||
import org.opsli.plugins.cache.EhCachePlugin;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* @BelongsProject: opsli-boot
|
||||
* @BelongsPackage: org.opsli.core.cache.pushsub.handler
|
||||
* @Author: Parker
|
||||
* @CreateTime: 2020-09-15 16:24
|
||||
* @Description: 用户组织消息处理
|
||||
*/
|
||||
@Slf4j
|
||||
public class OrgHandler implements RedisPushSubHandler{
|
||||
|
||||
@Autowired
|
||||
EhCachePlugin ehCachePlugin;
|
||||
|
||||
@Override
|
||||
public PushSubType getType() {
|
||||
return PushSubType.ORG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handler(JSONObject msgJson) {
|
||||
// 用户刷新
|
||||
this.orgHandler(msgJson);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户组织数据处理
|
||||
* @param msgJson
|
||||
*/
|
||||
private void orgHandler(JSONObject msgJson){
|
||||
JSONObject data = msgJson.getJSONObject(MsgArgsType.ORG_USER_DATA.toString());
|
||||
// 数据为空则不执行
|
||||
if(data == null) return;
|
||||
|
||||
// 获得用户ID
|
||||
String userId = (String) msgJson.get(MsgArgsType.ORG_USER_ID.toString());
|
||||
if(StringUtils.isEmpty(userId)){
|
||||
return;
|
||||
}
|
||||
|
||||
// 先删除
|
||||
ehCachePlugin.delete(CacheConstants.HOT_DATA, OrgUtil.PREFIX_CODE + userId);
|
||||
// 清除空拦截
|
||||
CacheUtil.delNilFlag(OrgUtil.PREFIX_CODE + userId);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.opsli.core.cache.pushsub.msgs;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.opsli.api.wrapper.system.menu.MenuModel;
|
||||
import org.opsli.api.wrapper.system.user.UserOrgRefModel;
|
||||
import org.opsli.core.cache.pushsub.enums.MsgArgsType;
|
||||
import org.opsli.core.cache.pushsub.enums.PushSubType;
|
||||
import org.opsli.core.cache.pushsub.receiver.RedisPushSubReceiver;
|
||||
import org.opsli.plugins.redis.pushsub.entity.BaseSubMessage;
|
||||
|
||||
/**
|
||||
* @BelongsProject: opsli-boot
|
||||
* @BelongsPackage: org.opsli.core.cache.pushsub.msgs
|
||||
* @Author: Parker
|
||||
* @CreateTime: 2020-09-15 16:50
|
||||
* @Description: 用户组织消息
|
||||
*/
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public final class OrgMsgFactory extends BaseSubMessage{
|
||||
|
||||
/** 通道 */
|
||||
private static final String CHANNEL = RedisPushSubReceiver.BASE_CHANNEL+RedisPushSubReceiver.CHANNEL;
|
||||
|
||||
private OrgMsgFactory(){}
|
||||
|
||||
/**
|
||||
* 构建消息 - 组织
|
||||
*/
|
||||
public static BaseSubMessage createOrgMsg(UserOrgRefModel orgRefModel){
|
||||
BaseSubMessage baseSubMessage = new BaseSubMessage();
|
||||
// 数据
|
||||
JSONObject jsonObj = new JSONObject();
|
||||
jsonObj.put(MsgArgsType.ORG_USER_ID.toString(), orgRefModel.getUserId());
|
||||
jsonObj.put(MsgArgsType.ORG_USER_DATA.toString(), orgRefModel);
|
||||
|
||||
// 用户
|
||||
baseSubMessage.build(CHANNEL,PushSubType.ORG.toString(),jsonObj);
|
||||
return baseSubMessage;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,183 @@
|
||||
/**
|
||||
* Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.opsli.core.utils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.opsli.api.base.result.ResultVo;
|
||||
import org.opsli.api.web.system.menu.MenuApi;
|
||||
import org.opsli.api.web.system.user.UserApi;
|
||||
import org.opsli.api.wrapper.system.menu.MenuModel;
|
||||
import org.opsli.api.wrapper.system.user.UserOrgRefModel;
|
||||
import org.opsli.core.cache.local.CacheUtil;
|
||||
import org.opsli.core.cache.pushsub.msgs.MenuMsgFactory;
|
||||
import org.opsli.core.cache.pushsub.msgs.OrgMsgFactory;
|
||||
import org.opsli.plugins.redis.RedisLockPlugins;
|
||||
import org.opsli.plugins.redis.RedisPlugin;
|
||||
import org.opsli.plugins.redis.lock.RedisLock;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import static org.opsli.common.constants.OrderConstants.UTIL_ORDER;
|
||||
|
||||
/**
|
||||
* @BelongsProject: opsli-boot
|
||||
* @BelongsPackage: org.opsli.core.utils
|
||||
* @Author: Parker
|
||||
* @CreateTime: 2020-09-19 20:03
|
||||
* @Description: 组织机构工具类
|
||||
*/
|
||||
@Slf4j
|
||||
@Order(UTIL_ORDER)
|
||||
@Component
|
||||
@AutoConfigureAfter({RedisPlugin.class , RedisLockPlugins.class, UserApi.class})
|
||||
@Lazy(false)
|
||||
public class OrgUtil {
|
||||
|
||||
/** 前缀 */
|
||||
public static final String PREFIX_CODE = "org:userId:";
|
||||
|
||||
|
||||
/** Redis插件 */
|
||||
private static RedisPlugin redisPlugin;
|
||||
|
||||
/** Redis分布式锁 */
|
||||
private static RedisLockPlugins redisLockPlugins;
|
||||
|
||||
/** 用户 Api */
|
||||
private static UserApi userApi;
|
||||
|
||||
|
||||
/**
|
||||
* 根据 userId 获得用户组织
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
public static UserOrgRefModel getOrgByUserId(String userId){
|
||||
// 先从缓存里拿
|
||||
UserOrgRefModel orgRefModel = CacheUtil.get(PREFIX_CODE + userId, UserOrgRefModel.class);
|
||||
if (orgRefModel != null){
|
||||
return orgRefModel;
|
||||
}
|
||||
|
||||
// 拿不到 --------
|
||||
// 防止缓存穿透判断
|
||||
boolean hasNilFlag = CacheUtil.hasNilFlag(PREFIX_CODE + userId);
|
||||
if(hasNilFlag){
|
||||
return null;
|
||||
}
|
||||
|
||||
// 锁凭证 redisLock 贯穿全程
|
||||
RedisLock redisLock = new RedisLock();
|
||||
redisLock.setLockName(PREFIX_CODE + userId)
|
||||
.setAcquireTimeOut(3000L)
|
||||
.setLockTimeOut(5000L);
|
||||
|
||||
try {
|
||||
// 这里增加分布式锁 防止缓存击穿
|
||||
// ============ 尝试加锁
|
||||
redisLock = redisLockPlugins.tryLock(redisLock);
|
||||
if(redisLock == null){
|
||||
return null;
|
||||
}
|
||||
|
||||
// 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求
|
||||
orgRefModel = CacheUtil.get(PREFIX_CODE + userId, UserOrgRefModel.class);
|
||||
if (orgRefModel != null){
|
||||
return orgRefModel;
|
||||
}
|
||||
|
||||
// 查询数据库
|
||||
ResultVo<UserOrgRefModel> resultVo = userApi.getOrgInfoByUserId(userId);
|
||||
if(resultVo.isSuccess()){
|
||||
orgRefModel = resultVo.getData();
|
||||
// 存入缓存
|
||||
CacheUtil.put(PREFIX_CODE + userId, orgRefModel);
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error(e.getMessage(),e);
|
||||
}finally {
|
||||
// ============ 释放锁
|
||||
redisLockPlugins.unLock(redisLock);
|
||||
redisLock = null;
|
||||
}
|
||||
|
||||
if(orgRefModel == null){
|
||||
// 设置空变量 用于防止穿透判断
|
||||
CacheUtil.putNilFlag(PREFIX_CODE + userId);
|
||||
return null;
|
||||
}
|
||||
|
||||
return orgRefModel;
|
||||
}
|
||||
|
||||
|
||||
// ============== 刷新缓存 ==============
|
||||
|
||||
/**
|
||||
* 刷新用户组织 - 删就完了
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
public static void refreshMenu(String userId){
|
||||
if(StringUtils.isEmpty(userId)){
|
||||
return;
|
||||
}
|
||||
|
||||
UserOrgRefModel orgRefModel = CacheUtil.get(PREFIX_CODE + userId, UserOrgRefModel.class);
|
||||
boolean hasNilFlag = CacheUtil.hasNilFlag(PREFIX_CODE + userId);
|
||||
|
||||
// 只要不为空 则执行刷新
|
||||
if (hasNilFlag){
|
||||
// 清除空拦截
|
||||
CacheUtil.delNilFlag(PREFIX_CODE + userId);
|
||||
}
|
||||
|
||||
if(orgRefModel != null){
|
||||
// 先删除
|
||||
CacheUtil.del(PREFIX_CODE + userId);
|
||||
|
||||
// 发送通知消息
|
||||
redisPlugin.sendMessage(
|
||||
OrgMsgFactory.createOrgMsg(orgRefModel)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// =====================================
|
||||
|
||||
@Autowired
|
||||
public void setRedisPlugin(RedisPlugin redisPlugin) {
|
||||
OrgUtil.redisPlugin = redisPlugin;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setRedisLockPlugins(RedisLockPlugins redisLockPlugins) {
|
||||
OrgUtil.redisLockPlugins = redisLockPlugins;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setUserApi(UserApi userApi) {
|
||||
OrgUtil.userApi = userApi;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in new issue