mirror of
https://github.com/zongzibinbin/MallChat.git
synced 2026-03-14 06:03:42 +08:00
feat:
1.前后端交互改版 2.艾特成员功能 3.用户名片卡功能
This commit is contained in:
@@ -7,7 +7,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -63,13 +63,13 @@ public class MessageMark implements Serializable {
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField("create_time")
|
||||
private LocalDateTime createTime;
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
@TableField("update_time")
|
||||
private LocalDateTime updateTime;
|
||||
private Date updateTime;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -25,4 +26,6 @@ public class MessageExtra implements Serializable {
|
||||
private Map<String, String> urlTitleMap;
|
||||
//消息撤回详情
|
||||
private MsgRecall recall;
|
||||
//艾特的uid
|
||||
private List<Long> atUidList;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,16 @@ public class RedisKey {
|
||||
*/
|
||||
public static final String USER_TOKEN_STRING = "userToken:uid_%d";
|
||||
|
||||
/**
|
||||
* 用户的信息更新时间
|
||||
*/
|
||||
public static final String USER_MODIFY_STRING = "userModify:uid_%d";
|
||||
|
||||
/**
|
||||
* 用户的信息汇总
|
||||
*/
|
||||
public static final String USER_SUMMARY_STRING = "userSummary:uid_%d";
|
||||
|
||||
public static String getKey(String key, Object... objects) {
|
||||
return BASE_KEY + String.format(key, objects);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.abin.mallchat.common.common.service.cache;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.abin.mallchat.common.common.utils.RedisUtils;
|
||||
import org.springframework.data.util.Pair;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Description: redis string类型的批量缓存框架
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-06-10
|
||||
*/
|
||||
public abstract class AbstractRedisStringCache<IN, OUT> implements BatchCache<IN, OUT> {
|
||||
|
||||
private Class<OUT> outClass;
|
||||
|
||||
public AbstractRedisStringCache() {
|
||||
ParameterizedType genericSuperclass = (ParameterizedType) this.getClass().getGenericSuperclass();
|
||||
this.outClass = (Class<OUT>) genericSuperclass.getActualTypeArguments()[1];
|
||||
}
|
||||
|
||||
protected abstract String getKey(IN req);
|
||||
|
||||
protected abstract Long getExpireSeconds();
|
||||
|
||||
protected abstract Map<IN, OUT> load(List<IN> req);
|
||||
|
||||
@Override
|
||||
public OUT get(IN req) {
|
||||
return getBatch(Collections.singletonList(req)).get(req);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<IN, OUT> getBatch(List<IN> req) {
|
||||
List<String> keys = req.stream().map(this::getKey).collect(Collectors.toList());
|
||||
List<OUT> valueList = RedisUtils.mget(keys, outClass);
|
||||
List<IN> loadReqs = new ArrayList<>();
|
||||
for (int i = 0; i < valueList.size(); i++) {
|
||||
if (Objects.isNull(valueList.get(i))) {
|
||||
loadReqs.add(req.get(i));
|
||||
}
|
||||
}
|
||||
Map<IN, OUT> load = new HashMap<>();
|
||||
//不足的重新加载进redis
|
||||
if (CollectionUtil.isNotEmpty(loadReqs)) {
|
||||
load = load(loadReqs);
|
||||
Map<String, OUT> loadMap = load.entrySet().stream()
|
||||
.map(a -> Pair.of(getKey(a.getKey()), a.getValue()))
|
||||
.collect(Collectors.toMap(Pair::getFirst, Pair::getSecond));
|
||||
RedisUtils.mset(loadMap, getExpireSeconds());
|
||||
}
|
||||
|
||||
//组装最后的结果
|
||||
Map<IN, OUT> resultMap = new HashMap<>();
|
||||
for (int i = 0; i < req.size(); i++) {
|
||||
IN in = req.get(i);
|
||||
OUT out = Optional.ofNullable(valueList.get(i))
|
||||
.orElse(load.get(in));
|
||||
resultMap.put(in, out);
|
||||
}
|
||||
return resultMap;
|
||||
}
|
||||
}
|
||||
16
mallchat-common/src/main/java/com/abin/mallchat/common/common/service/cache/BatchCache.java
vendored
Normal file
16
mallchat-common/src/main/java/com/abin/mallchat/common/common/service/cache/BatchCache.java
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
package com.abin.mallchat.common.common.service.cache;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface BatchCache<IN, OUT> {
|
||||
/**
|
||||
* 获取单个
|
||||
*/
|
||||
OUT get(IN req);
|
||||
|
||||
/**
|
||||
* 获取批量
|
||||
*/
|
||||
Map<IN, OUT> getBatch(List<IN> req);
|
||||
}
|
||||
@@ -66,7 +66,7 @@ public abstract class AbstractUrlTitleDiscover implements UrlTitleDiscover {
|
||||
protected Document getUrlDocument(String matchUrl) {
|
||||
try {
|
||||
Connection connect = Jsoup.connect(matchUrl);
|
||||
connect.timeout(1000);
|
||||
connect.timeout(2000);
|
||||
return connect.get();
|
||||
} catch (Exception e) {
|
||||
log.error("find title error:url:{}", matchUrl, e);
|
||||
|
||||
@@ -51,6 +51,13 @@ public class UserBackpackDao extends ServiceImpl<UserBackpackMapper, UserBackpac
|
||||
.list();
|
||||
}
|
||||
|
||||
public List<UserBackpack> getByItemIds(List<Long> uids, List<Long> itemIds) {
|
||||
return lambdaQuery().in(UserBackpack::getUid, uids)
|
||||
.in(UserBackpack::getItemId, itemIds)
|
||||
.eq(UserBackpack::getStatus, YesOrNoEnum.NO.getStatus())
|
||||
.list();
|
||||
}
|
||||
|
||||
public UserBackpack getByIdp(String idempotent) {
|
||||
return lambdaQuery().eq(UserBackpack::getIdempotent, idempotent).one();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.abin.mallchat.common.user.dao;
|
||||
|
||||
import com.abin.mallchat.common.common.domain.enums.NormalOrNoEnum;
|
||||
import com.abin.mallchat.common.user.domain.entity.User;
|
||||
import com.abin.mallchat.common.user.mapper.UserMapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
@@ -7,6 +8,8 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户表 服务实现类
|
||||
@@ -40,4 +43,14 @@ public class UserDao extends ServiceImpl<UserMapper, User> {
|
||||
public User getByName(String name) {
|
||||
return lambdaQuery().eq(User::getName, name).one();
|
||||
}
|
||||
|
||||
public List<User> getMemberList() {
|
||||
return lambdaQuery()
|
||||
.eq(User::getStatus, NormalOrNoEnum.NORMAL.getStatus())
|
||||
.orderByDesc(User::getUpdateTime)//最近活跃的1000个人,可以用lastOptTime字段,但是该字段没索引,updateTime可平替
|
||||
.last("limit 1000")//毕竟是大群聊,人数需要做个限制
|
||||
.select(User::getId, User::getName, User::getAvatar)
|
||||
.list();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.abin.mallchat.common.user.domain.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
|
||||
/**
|
||||
* Description: 修改用户名
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-03-23
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ItemInfoDTO {
|
||||
@ApiModelProperty(value = "徽章id")
|
||||
private Long itemId;
|
||||
@ApiModelProperty("徽章图像")
|
||||
private String img;
|
||||
@ApiModelProperty("徽章说明")
|
||||
private String describe;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.abin.mallchat.common.user.domain.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* Description: 修改用户名
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-03-23
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class SummeryInfoDTO {
|
||||
@ApiModelProperty(value = "用户id")
|
||||
private Long uid;
|
||||
@ApiModelProperty(value = "用户昵称")
|
||||
private String name;
|
||||
@ApiModelProperty(value = "用户头像")
|
||||
private String avatar;
|
||||
@ApiModelProperty(value = "归属地")
|
||||
private String locPlace;
|
||||
@ApiModelProperty("佩戴的徽章id")
|
||||
private Long wearingItemId;
|
||||
@ApiModelProperty(value = "用户拥有的徽章id列表")
|
||||
List<Long> itemIds;
|
||||
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -49,13 +49,13 @@ public class Black implements Serializable {
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField("create_time")
|
||||
private LocalDateTime createTime;
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
@TableField("update_time")
|
||||
private LocalDateTime updateTime;
|
||||
private Date updateTime;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -52,13 +52,13 @@ public class ItemConfig implements Serializable {
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField("create_time")
|
||||
private LocalDateTime createTime;
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
@TableField("update_time")
|
||||
private LocalDateTime updateTime;
|
||||
private Date updateTime;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -41,13 +41,13 @@ public class Role implements Serializable {
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField("create_time")
|
||||
private LocalDateTime createTime;
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
@TableField("update_time")
|
||||
private LocalDateTime updateTime;
|
||||
private Date updateTime;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -61,13 +61,13 @@ public class UserBackpack implements Serializable {
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField("create_time")
|
||||
private LocalDateTime createTime;
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
@TableField("update_time")
|
||||
private LocalDateTime updateTime;
|
||||
private Date updateTime;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -95,6 +95,16 @@ public class UserCache {
|
||||
return cursorUtils.getCursorPageByRedis(pageBaseReq, RedisKey.getKey(RedisKey.OFFLINE_UID_ZET), Long::parseLong);
|
||||
}
|
||||
|
||||
public List<Long> getUserModifyTime(List<Long> uidList) {
|
||||
List<String> keys = uidList.stream().map(uid -> RedisKey.getKey(RedisKey.USER_MODIFY_STRING, uid)).collect(Collectors.toList());
|
||||
return RedisUtils.mget(keys, Long.class);
|
||||
}
|
||||
|
||||
public void refreshUserModifyTime(Long uid) {
|
||||
String key = RedisKey.getKey(RedisKey.USER_MODIFY_STRING, uid);
|
||||
RedisUtils.set(key, new Date().getTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息,盘路缓存模式
|
||||
*/
|
||||
@@ -120,6 +130,11 @@ public class UserCache {
|
||||
return map;
|
||||
}
|
||||
|
||||
public void userInfoChange(Long uid) {
|
||||
delUserInfo(uid);
|
||||
refreshUserModifyTime(uid);
|
||||
}
|
||||
|
||||
public void delUserInfo(Long uid) {
|
||||
String key = RedisKey.getKey(RedisKey.USER_INFO_STRING, uid);
|
||||
RedisUtils.del(key);
|
||||
|
||||
40
mallchat-common/src/main/java/com/abin/mallchat/common/user/service/cache/UserInfoCache.java
vendored
Normal file
40
mallchat-common/src/main/java/com/abin/mallchat/common/user/service/cache/UserInfoCache.java
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
package com.abin.mallchat.common.user.service.cache;
|
||||
|
||||
import com.abin.mallchat.common.common.constant.RedisKey;
|
||||
import com.abin.mallchat.common.common.service.cache.AbstractRedisStringCache;
|
||||
import com.abin.mallchat.common.user.dao.UserDao;
|
||||
import com.abin.mallchat.common.user.domain.entity.User;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Description: 用户基本信息的缓存
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-06-10
|
||||
*/
|
||||
@Component
|
||||
public class UserInfoCache extends AbstractRedisStringCache<Long, User> {
|
||||
@Autowired
|
||||
private UserDao userDao;
|
||||
|
||||
@Override
|
||||
protected String getKey(Long uid) {
|
||||
return RedisKey.getKey(RedisKey.USER_INFO_STRING, uid);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Long getExpireSeconds() {
|
||||
return 5 * 60L;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<Long, User> load(List<Long> uidList) {
|
||||
List<User> needLoadUserList = userDao.listByIds(uidList);
|
||||
return needLoadUserList.stream().collect(Collectors.toMap(User::getId, Function.identity()));
|
||||
}
|
||||
}
|
||||
68
mallchat-common/src/main/java/com/abin/mallchat/common/user/service/cache/UserSummaryCache.java
vendored
Normal file
68
mallchat-common/src/main/java/com/abin/mallchat/common/user/service/cache/UserSummaryCache.java
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
package com.abin.mallchat.common.user.service.cache;
|
||||
|
||||
import com.abin.mallchat.common.common.constant.RedisKey;
|
||||
import com.abin.mallchat.common.common.service.cache.AbstractRedisStringCache;
|
||||
import com.abin.mallchat.common.user.dao.UserBackpackDao;
|
||||
import com.abin.mallchat.common.user.domain.dto.SummeryInfoDTO;
|
||||
import com.abin.mallchat.common.user.domain.entity.*;
|
||||
import com.abin.mallchat.common.user.domain.enums.ItemTypeEnum;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Description: 用户所有信息的缓存
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-06-10
|
||||
*/
|
||||
@Component
|
||||
public class UserSummaryCache extends AbstractRedisStringCache<Long, SummeryInfoDTO> {
|
||||
@Autowired
|
||||
private UserInfoCache userInfoCache;
|
||||
@Autowired
|
||||
private UserBackpackDao userBackpackDao;
|
||||
@Autowired
|
||||
private ItemCache itemCache;
|
||||
|
||||
@Override
|
||||
protected String getKey(Long uid) {
|
||||
return RedisKey.getKey(RedisKey.USER_SUMMARY_STRING, uid);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Long getExpireSeconds() {
|
||||
return 10 * 60L;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<Long, SummeryInfoDTO> load(List<Long> uidList) {//后续可优化徽章信息也异步加载
|
||||
//用户基本信息
|
||||
Map<Long, User> userMap = userInfoCache.getBatch(uidList);
|
||||
//用户徽章信息
|
||||
List<ItemConfig> itemConfigs = itemCache.getByType(ItemTypeEnum.BADGE.getType());
|
||||
List<Long> itemIds = itemConfigs.stream().map(ItemConfig::getId).collect(Collectors.toList());
|
||||
List<UserBackpack> backpacks = userBackpackDao.getByItemIds(uidList, itemIds);
|
||||
Map<Long, List<UserBackpack>> userBadgeMap = backpacks.stream().collect(Collectors.groupingBy(UserBackpack::getUid));
|
||||
//用户最后一次更新时间
|
||||
return uidList.stream().map(uid -> {
|
||||
SummeryInfoDTO summeryInfoDTO = new SummeryInfoDTO();
|
||||
User user = userMap.get(uid);
|
||||
if (Objects.isNull(user)) {
|
||||
return null;
|
||||
}
|
||||
List<UserBackpack> userBackpacks = userBadgeMap.getOrDefault(user.getId(), new ArrayList<>());
|
||||
summeryInfoDTO.setUid(user.getId());
|
||||
summeryInfoDTO.setName(user.getName());
|
||||
summeryInfoDTO.setAvatar(user.getAvatar());
|
||||
summeryInfoDTO.setLocPlace(Optional.ofNullable(user.getIpInfo()).map(IpInfo::getUpdateIpDetail).map(IpDetail::getCity).orElse(null));
|
||||
summeryInfoDTO.setWearingItemId(user.getItemId());
|
||||
summeryInfoDTO.setItemIds(userBackpacks.stream().map(UserBackpack::getItemId).collect(Collectors.toList()));
|
||||
return summeryInfoDTO;
|
||||
})
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toMap(SummeryInfoDTO::getUid, Function.identity()));
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.abin.mallchat.common.user.service.impl;
|
||||
|
||||
import cn.hutool.core.lang.TypeReference;
|
||||
|
||||
import cn.hutool.core.thread.NamedThreadFactory;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
@@ -13,7 +12,7 @@ import com.abin.mallchat.common.user.domain.entity.IpDetail;
|
||||
import com.abin.mallchat.common.user.domain.entity.IpInfo;
|
||||
import com.abin.mallchat.common.user.domain.entity.User;
|
||||
import com.abin.mallchat.common.user.service.IpService;
|
||||
import jodd.util.concurrent.ThreadFactoryBuilder;
|
||||
import com.abin.mallchat.common.user.service.cache.UserCache;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -21,7 +20,10 @@ import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Description: ip
|
||||
@@ -34,13 +36,13 @@ public class IpServiceImpl implements IpService, DisposableBean {
|
||||
private static ExecutorService executor = new ThreadPoolExecutor(1, 1,
|
||||
0L, TimeUnit.MILLISECONDS,
|
||||
new LinkedBlockingQueue<Runnable>(500),
|
||||
new NamedThreadFactory("refresh-ipDetail", (ThreadGroup)null,false,
|
||||
new NamedThreadFactory("refresh-ipDetail", (ThreadGroup) null, false,
|
||||
new GlobalUncaughtExceptionHandler()));
|
||||
|
||||
@Autowired
|
||||
private UserDao userDao;
|
||||
|
||||
|
||||
@Autowired
|
||||
private UserCache userCache;
|
||||
|
||||
|
||||
@Override
|
||||
@@ -62,6 +64,7 @@ public class IpServiceImpl implements IpService, DisposableBean {
|
||||
update.setId(uid);
|
||||
update.setIpInfo(ipInfo);
|
||||
userDao.updateById(update);
|
||||
userCache.userInfoChange(uid);
|
||||
} else {
|
||||
log.error("get ip detail fail ip:{},uid:{}", ip, uid);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user