付费动态头像

This commit is contained in:
khalil
2025-03-10 15:24:41 +08:00
parent 87f93d34b3
commit c8b48505dc
11 changed files with 217 additions and 101 deletions

View File

@@ -16,11 +16,9 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Created by yanpengcheng on 2019/4/10
*/
@RestController
@RequestMapping(value = "admin/qiniu")
@Deprecated
//@RestController
//@RequestMapping(value = "admin/qiniu")
public class QiniuUploadController extends BaseController {
@Autowired
private QinniuService qinniuService;

View File

@@ -129,6 +129,8 @@ public class UserVo {
@ApiModelProperty(value = "在审核中的新头像")
@ReplaceAppDomain
private String newAvatar;
@ApiModelProperty("上传动态头像金币价格")
private Long uploadGifAvatarPrice;
/**
* 贵族信息

View File

@@ -899,6 +899,7 @@ public enum RedisKey {
mini_game_switch_lock,//小游戏房切换加锁
user_avatar_under_review,//头像:审核中的用户头像
user_avatar_review_task,//头像:审核中的任务
user_avatar_paid_price,//头像:付费价格
user_album_review_task,//相册:审核中的任务
/**

View File

@@ -222,6 +222,9 @@ public enum BillObjTypeEnum {
RAMADAN_GIFT_SEND_RANK_GOLD(148, "斋月榜单奖池金币瓜分", BillTypeEnum.IN, CurrencyEnum.DIAMOND, BillDomainTypeEnum.ACTIVITY),
MINI_GAME_WEEK_JACKPOT_GOLD(149, "小游戏周榜奖池金币瓜分", BillTypeEnum.IN, CurrencyEnum.DIAMOND, BillDomainTypeEnum.ACTIVITY),
PAID_GIF_AVATAR_UPLOAD_GOLD(150, "付费动态头像上传", BillTypeEnum.OUT, CurrencyEnum.DIAMOND, BillDomainTypeEnum.DRESS_UP_SHOP),
PAID_GIF_AVATAR_UPLOAD_REFUND(151, "付费动态头像退款", BillTypeEnum.IN, CurrencyEnum.DIAMOND, BillDomainTypeEnum.DRESS_UP_SHOP),
;
BillObjTypeEnum(int value, String desc, BillTypeEnum type, CurrencyEnum currency, BillDomainTypeEnum domain) {

View File

@@ -97,4 +97,7 @@ public class UserDetailsVo {
private AgencyOwnerVo guildInfo;
private PersonalBackground usingPersonalBackground;
@ApiModelProperty("上传动态头像金币价格")
private Long uploadGifAvatarPrice;
}

View File

@@ -0,0 +1,165 @@
package com.accompany.business.service;
import com.accompany.business.model.UserPurse;
import com.accompany.business.model.family.Family;
import com.accompany.business.model.guild.Guild;
import com.accompany.business.param.neteasepush.NeteaseSendMsgParam;
import com.accompany.business.service.family.FamilyService;
import com.accompany.business.service.guild.GuildService;
import com.accompany.business.service.purse.UserPurseService;
import com.accompany.business.service.room.RoomService;
import com.accompany.business.util.VipUtil;
import com.accompany.common.config.SystemConfig;
import com.accompany.common.constant.Constant;
import com.accompany.common.netease.ErBanNetEaseService;
import com.accompany.common.netease.neteaseacc.result.BaseNetEaseRet;
import com.accompany.common.redis.RedisKey;
import com.accompany.common.status.BusiStatus;
import com.accompany.common.utils.DateTimeUtil;
import com.accompany.common.utils.ImageFileUtils;
import com.accompany.common.utils.StringUtils;
import com.accompany.core.base.SpringContextHolder;
import com.accompany.core.enumeration.BillObjTypeEnum;
import com.accompany.core.enumeration.I18nAlertEnum;
import com.accompany.core.exception.ServiceException;
import com.accompany.core.model.Room;
import com.accompany.core.model.Users;
import com.accompany.core.service.base.BaseService;
import com.accompany.core.service.user.UsersBaseService;
import com.accompany.core.util.I18NMessageSourceUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.Date;
@Slf4j
@Service
public class UploadAvatarService extends BaseService {
@Autowired
private UsersBaseService usersBaseService;
@Autowired
private ErBanNetEaseService erBanNetEaseService;
@Autowired
private SendSysMsgService sendSysMsgService;
@Autowired
private RoomService roomService;
@Autowired
private GuildService guildService;
@Autowired
private FamilyService familyService;
@Autowired
private UserPurseService userPurseService;
private final Long gifAvatarGoldPrice = 1000L;
public long getGifAvatarGoldPrice(){
return gifAvatarGoldPrice;
}
public Long checkAvatarUrlAndPaid(Long uid, String avatarUrl){
if (!ImageFileUtils.isImageFile(avatarUrl)) {
throw new ServiceException(BusiStatus.FILE_FORMAT_ERROR);
}
UserPurse afterPurse = null;
if (ImageFileUtils.isGif(avatarUrl)
&& !VipUtil.hasVipAuthItem(uid, Constant.VipAuthType.GIF_AVATAR)
&& null == (afterPurse = userPurseService.subDiamond(uid, gifAvatarGoldPrice.doubleValue(), BillObjTypeEnum.PAID_GIF_AVATAR_UPLOAD_GOLD))) {
throw new ServiceException(BusiStatus.CANNOT_UPLOAD_GIF);
}
return afterPurse != null ? gifAvatarGoldPrice : null;
}
public void updateAvatar(String newAvatar, Long uid, String redisKey, String taskId){
String uidStr = uid.toString();
if (redisKey.equals(RedisKey.user_avatar_under_review.getKey())){
Users users = usersBaseService.getUsersByUid(uid);
users.setAvatar(newAvatar);
usersBaseService.updateUser(users);
BaseNetEaseRet baseNetEaseRet = erBanNetEaseService.updateUserInfo(uidStr, users.getNick(), users.getAvatar(), null);
if (!baseNetEaseRet.isSuccess()) {
log.info("用户{}易盾头像审核回调taskId{}更新网易云账号信息异常异常编码={}", uidStr, taskId, baseNetEaseRet.getCode());
throw new ServiceException("处理异常!");
}
} else if (redisKey.equals(RedisKey.room_avatar_under_review.getKey())){
Room room = roomService.getRoomByUid(uid);
room.setAvatar(newAvatar);
roomService.update(room);
} else if (redisKey.equals(RedisKey.guild_avatar_under_review.getKey())) {
Guild guild = guildService.getVaildGuildByOwnerUid(uid);
if (null != guild) {
guildService.lambdaUpdate()
.set(Guild::getAvatar, newAvatar)
.eq(Guild::getId, guild.getId())
.update();
}
} else if (redisKey.equals(RedisKey.family_avatar_under_review.getKey())) {
Family family = familyService.getVaildFamilyByOwnerUid(uid);
if (null != family) {
familyService.lambdaUpdate()
.set(Family::getAvatar, newAvatar)
.eq(Family::getId, family.getId())
.update();
}
}
jedisService.hdel(RedisKey.user_avatar_review_task.getKey(), taskId);
delReviewAvatar(redisKey, uidStr);
}
public void reportReviewProfileFail(String uidStr, String avatarUrl) {
delReviewAvatar(RedisKey.user_avatar_under_review.getKey(), uidStr);
refundPaidAvatar(uidStr, avatarUrl);
SpringContextHolder.getBean(UploadAvatarService.class).profileAvatarReviewNoPassNotify(uidStr);
}
private void refundPaidAvatar(String uidStr, String avatarUrl) {
String paidCacheKey = String.join("_", uidStr, avatarUrl);
String priceStr = jedisService.hget(RedisKey.user_avatar_paid_price.getKey(), paidCacheKey);
if (StringUtils.isBlank(priceStr)){
return;
}
Long uid = Long.parseLong(uidStr);
Double price = Double.parseDouble(priceStr);
userPurseService.addDiamond(uid, price, BillObjTypeEnum.PAID_GIF_AVATAR_UPLOAD_REFUND);
}
public void cacheReviewAvatar(String redisKey, String uidStr, String avatarUrl, Long price) {
jedisService.hset(redisKey, uidStr, avatarUrl);
//付费逻辑
if (null == price || price < 0L){
return;
}
String cacheKey = String.join("_", uidStr, avatarUrl);
jedisService.hset(RedisKey.user_avatar_paid_price.getKey(), cacheKey, price.toString());
}
public void delReviewAvatar(String redisKey, String uidStr) {
jedisService.hdel(redisKey, uidStr);
}
@Async
public void profileAvatarReviewNoPassNotify(String uid) {
if (StringUtils.isEmpty(uid)) return;
NeteaseSendMsgParam msg = new NeteaseSendMsgParam();
msg.setOpe(0);
msg.setType(0);
msg.setFrom(SystemConfig.secretaryUid);
msg.setTo(uid);
String message = I18NMessageSourceUtil.getMessage(I18nAlertEnum.UPLOAD_AVATAR, new Object[]{DateTimeUtil.converDateToLocalDate(new Date())}, Long.valueOf(uid));
msg.setBody(message);
sendSysMsgService.sendMsg(msg);
}
}

View File

@@ -4,19 +4,12 @@ import cn.hutool.core.util.ObjectUtil;
import com.accompany.business.dto.yidun.AntispamDto;
import com.accompany.business.dto.yidun.YidunCallBackDataDto;
import com.accompany.business.model.PrivatePhoto;
import com.accompany.business.model.family.Family;
import com.accompany.business.model.guild.Guild;
import com.accompany.business.mybatismapper.PrivatePhotoMapper;
import com.accompany.business.param.neteasepush.NeteaseSendMsgParam;
import com.accompany.business.service.family.FamilyService;
import com.accompany.business.service.guild.GuildService;
import com.accompany.business.service.room.RoomService;
import com.accompany.business.service.user.PrivatePhotoService;
import com.accompany.common.config.SystemConfig;
import com.accompany.common.config.YidunImageConfig;
import com.accompany.common.constant.Constant;
import com.accompany.common.netease.ErBanNetEaseService;
import com.accompany.common.netease.neteaseacc.result.BaseNetEaseRet;
import com.accompany.common.redis.RedisKey;
import com.accompany.common.status.BusiStatus;
import com.accompany.common.utils.DateTimeUtil;
@@ -24,11 +17,8 @@ import com.accompany.common.utils.StringUtils;
import com.accompany.core.base.SpringContextHolder;
import com.accompany.core.enumeration.I18nAlertEnum;
import com.accompany.core.exception.ServiceException;
import com.accompany.core.model.Room;
import com.accompany.core.model.Users;
import com.accompany.core.result.YidunBusiResult;
import com.accompany.core.service.base.BaseService;
import com.accompany.core.service.user.UsersBaseService;
import com.accompany.core.util.I18NMessageSourceUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -54,10 +44,6 @@ public class YidunCallbackService extends BaseService {
private final List<Integer> reviewFailList = Arrays.asList(Constant.YidunReviewStatus.review_fail);
private final List<Integer> successlList = Arrays.asList(Constant.YidunReviewStatus.review_success);
@Autowired
private UsersBaseService usersBaseService;
@Autowired
private ErBanNetEaseService erBanNetEaseService;
@Autowired
private SendSysMsgService sendSysMsgService;
@Autowired
@@ -66,11 +52,7 @@ public class YidunCallbackService extends BaseService {
@Autowired
private PrivatePhotoService privatePhotoService;
@Autowired
private RoomService roomService;
@Autowired
private GuildService guildService;
@Autowired
private FamilyService familyService;
private UploadAvatarService uploadAvatarService;
public YidunBusiResult reportReviewRsult(String secretId, String businessId, String signature, String callbackData) {
YidunBusiResult yidunBusiResult = new YidunBusiResult(BusiStatus.SUCCESS);
@@ -120,7 +102,7 @@ public class YidunCallbackService extends BaseService {
if (StringUtils.isEmpty(newAvatar)) {
logger.info("用户{}易盾头像{}审核回调taskId{}查询头像为空", uidStr, newAvatar, taskId);
jedisService.hdel(RedisKey.user_avatar_review_task.getKey(), taskId);
jedisService.hdel(redisKey, uidStr);
uploadAvatarService.delReviewAvatar(redisKey, uidStr);
return yidunBusiResult;
}
@@ -129,7 +111,7 @@ public class YidunCallbackService extends BaseService {
return new YidunBusiResult(500, String.format("审核未完成状态%s", status));
}else if (reviewFailList.contains(status)) {
logger.info("易盾头像 业务key {} {} {} 失败,失败原因{}", redisKey, newAvatar, taskId, antispamDto.getFailureReason());
reviewProfileFail(taskId, uidStr);
reviewProfileFail(taskId, uidStr, newAvatar);
return yidunBusiResult;
}else if (!successlList.contains(status)) {
logger.info("用户{}易盾头像{}审核{}未知的审核状态{}", uidStr, newAvatar, taskId, status);
@@ -146,7 +128,7 @@ public class YidunCallbackService extends BaseService {
}else if (Constant.YidunReviewSuggestion.no_pass.equals(suggestion)) {
logger.info("用户{}易盾头像{}审核taskId{}不通过{}", uidStr, newAvatar, taskId, gson.toJson(antispamDto.getLabels()));
reviewProfileFail(taskId, uidStr);
reviewProfileFail(taskId, uidStr, newAvatar);
}else {
throw new ServiceException(BusiStatus.SUGGESTION_VALUE_STATUS_UNKNOWN_SUGGESTION.format(suggestion));
}
@@ -161,50 +143,13 @@ public class YidunCallbackService extends BaseService {
}
public void updateAvatar(String newAvatar, Long uid, String redisKey, String taskId){
String uidStr = uid.toString();
if (redisKey.equals(RedisKey.user_avatar_under_review.getKey())){
Users users = usersBaseService.getUsersByUid(uid);
users.setAvatar(newAvatar);
usersBaseService.updateUser(users);
BaseNetEaseRet baseNetEaseRet = erBanNetEaseService.updateUserInfo(uidStr, users.getNick(), users.getAvatar(), null);
if (200 != baseNetEaseRet.getCode()) {
log.info("用户{}易盾头像审核回调taskId{}更新网易云账号信息异常异常编码={}", uidStr, taskId, baseNetEaseRet.getCode());
throw new ServiceException("处理异常!");
}
} else if (redisKey.equals(RedisKey.room_avatar_under_review.getKey())){
Room room = roomService.getRoomByUid(uid);
room.setAvatar(newAvatar);
roomService.update(room);
} else if (redisKey.equals(RedisKey.guild_avatar_under_review.getKey())) {
Guild guild = guildService.getVaildGuildByOwnerUid(uid);
if (null != guild) {
guildService.lambdaUpdate()
.set(Guild::getAvatar, newAvatar)
.eq(Guild::getId, guild.getId())
.update();
}
} else if (redisKey.equals(RedisKey.family_avatar_under_review.getKey())) {
Family family = familyService.getVaildFamilyByOwnerUid(uid);
if (null != family) {
familyService.lambdaUpdate()
.set(Family::getAvatar, newAvatar)
.eq(Family::getId, family.getId())
.update();
}
}
uploadAvatarService.updateAvatar(newAvatar, uid, redisKey, taskId);
jedisService.hdel(RedisKey.user_avatar_review_task.getKey(), taskId);
jedisService.hdel(redisKey, uidStr);
}
private void reviewProfileFail(String taskId, String uidStr) {
SpringContextHolder.getBean(YidunCallbackService.class).profileAvatarReviewNoPassNotify(uidStr);
private void reviewProfileFail(String taskId, String uidStr, String avatarUrl) {
jedisService.hdel(RedisKey.user_avatar_review_task.getKey(), taskId);
jedisService.hdel(RedisKey.user_avatar_under_review.getKey(), uidStr);
uploadAvatarService.reportReviewProfileFail(uidStr, avatarUrl);
}
private void reviewAlbumFail(String taskId, Long uid, Long pid) {

View File

@@ -15,6 +15,7 @@ import cn.hutool.core.util.StrUtil;
import com.accompany.business.dto.yidun.*;
import com.accompany.business.sensitvienew.SensitiveConstant;
import com.accompany.business.sensitvienew.SensitiveFilterUtil;
import com.accompany.business.service.UploadAvatarService;
import com.accompany.business.service.YidunCallbackService;
import com.accompany.common.config.YidunCheckConfig;
import com.accompany.common.config.YidunImageConfig;
@@ -155,8 +156,8 @@ public class YidunCheckUtil {
*
* @param avatar
*/
public static void reviewAvatar(Long uid, String avatar) {
reviewAvatar(uid, avatar, RedisKey.user_avatar_under_review.getKey());
public static void reviewAvatar(Long uid, String avatar, String redisKey) {
reviewAvatar(uid, avatar, redisKey, null);
}
/**
@@ -164,7 +165,7 @@ public class YidunCheckUtil {
*
* @param avatar
*/
public static void reviewAvatar(Long uid, String avatar, String redisKey) {
public static void reviewAvatar(Long uid, String avatar, String redisKey, Long price) {
log.info("用户{}进行头像{}上传审核", uid, avatar);
if (StringUtils.isBlank(avatar) || ObjectUtil.isNull(uid))
return;
@@ -174,7 +175,7 @@ public class YidunCheckUtil {
SpringContextHolder.getBean(JedisService.class).hset(redisKey, String.valueOf(uid), avatar);
SpringContextHolder.getBean(JedisService.class).hset(RedisKey.user_avatar_review_task.getKey(), taskId, String.valueOf(uid));
SpringContextHolder.getBean(YidunCallbackService.class).updateAvatar(avatar, uid, redisKey, taskId);
SpringContextHolder.getBean(UploadAvatarService.class).updateAvatar(avatar, uid, redisKey, taskId);
return;
}
@@ -221,7 +222,7 @@ public class YidunCheckUtil {
String taskId = jObject.get("taskId").getAsString();
log.info("用户{}头像{}审核{}上传成功", uid, name, taskId);
SpringContextHolder.getBean(JedisService.class).hset(redisKey, String.valueOf(uid), avatar);
SpringContextHolder.getBean(UploadAvatarService.class).cacheReviewAvatar(redisKey, String.valueOf(uid), avatar, price);
SpringContextHolder.getBean(JedisService.class).hset(RedisKey.user_avatar_review_task.getKey(), taskId, String.valueOf(uid));
}
} else {

View File

@@ -120,21 +120,22 @@ public class UserDetailsService extends BaseService {
BeanUtils.copyProperties(userVo, userDetailsVo);
//把头像当做第一张图片
PrivatePhotoVo privatePhotoVo = null;
if (StringUtils.isNotBlank(userVo.getAvatar())) {
privatePhotoVo = new PrivatePhotoVo();
privatePhotoVo.setPhotoUrl(userVo.getAvatar());
privatePhotoVo.setSeqNo(0);
}
if (privatePhotoVo != null) {
userDetailsVo.getPrivatePhoto().add(0, privatePhotoVo);
}
if (!selfUid.equals(uid)){
List<PrivatePhotoVo> privatePhotoVos = privatePhotoService.dealPrivatePhotoVo(userDetailsVo.getPrivatePhoto());
if (CollectionUtil.isEmpty(privatePhotoVos)) {
privatePhotoVos = Collections.emptyList();
}
userDetailsVo.setPrivatePhoto(privatePhotoVos);
} else {
PrivatePhotoVo privatePhotoVo = null;
if (StringUtils.isNotBlank(userVo.getAvatar())) {
privatePhotoVo = new PrivatePhotoVo();
privatePhotoVo.setPhotoUrl(userVo.getAvatar());
privatePhotoVo.setSeqNo(0);
}
if (privatePhotoVo != null) {
userDetailsVo.getPrivatePhoto().add(0, privatePhotoVo);
}
}
CountDownLatch cdl = new CountDownLatch(4);

View File

@@ -16,6 +16,7 @@ import com.accompany.business.mybatismapper.UserFrozenRecordMapper;
import com.accompany.business.mybatismapper.UsersMapperExpend;
import com.accompany.business.param.UserParam;
import com.accompany.business.sensitvienew.SensitiveFilterUtil;
import com.accompany.business.service.UploadAvatarService;
import com.accompany.business.service.UserRoomCardService;
import com.accompany.business.service.account.AccountBlockService;
import com.accompany.business.service.car.CarportService;
@@ -76,6 +77,7 @@ import com.accompany.core.vo.car.CarportVo;
import com.accompany.core.vo.headwear.UserHeadwearVo;
import com.accompany.core.vo.live.LiveUserInfoSkillVo;
import com.accompany.core.vo.user.UserNameplateVo;
import com.accompany.core.vo.vip.UserVipInfoVO;
import com.accompany.payment.service.RechargeUserService;
import com.accompany.sms.service.SmsService;
import com.alibaba.fastjson.JSONObject;
@@ -179,6 +181,8 @@ public class UsersService extends BaseService {
private PartitionInfoService partitionInfoService;
@Autowired
private RegionInfoService regionInfoService;
@Autowired
private UploadAvatarService uploadAvatarService;
public Users getUsersByUid(Long uid) {
if (uid == null) {
@@ -363,6 +367,7 @@ public class UsersService extends BaseService {
List<String> absSkillCardPics = skillCardUserRecordService.getUserAbsSkillCardPics(uid);
userVo.setAbsCardPics(absSkillCardPics);
userVo.setIsRechargeUser(rechargeUserService.isRechargeUser(uid));
return userVo;
}
@@ -439,7 +444,13 @@ public class UsersService extends BaseService {
userVo.setHallId(hallId);
userVo.setUserInfoSkillVo(userInfoSkillVo);
//userVo.setUserExpand(userExpand);
userVo.setUserVipInfoVO(VipUtil.getUserVipInfo(user.getUid()));
UserVipInfoVO userVipInfoVO = VipUtil.getUserVipInfo(user.getUid());
userVo.setUserVipInfoVO(userVipInfoVO);
//vip权限免费
Long uploadGifAvatarPrice = null != userVipInfoVO && userVipInfoVO.getUploadGifAvatar()? 0L: uploadAvatarService.getGifAvatarGoldPrice();
userVo.setUploadGifAvatarPrice(uploadGifAvatarPrice);
// 地区
if (null != user.getRegionId()){
@@ -485,19 +496,12 @@ public class UsersService extends BaseService {
if (!BlankUtil.isBlank(avatarUrl)) {
if (ObjectUtil.isNull(userDb)) {
users.setAvatar(avatarUrl);
} else {
if (!ImageFileUtils.isImageFile(avatarUrl)) {
throw new ServiceException(BusiStatus.FILE_FORMAT_ERROR);
}
if (ImageFileUtils.isGif(avatarUrl) &&
(ObjectUtil.isNull(userDb) || !VipUtil.hasVipAuthItem(userDb.getUid(), Constant.VipAuthType.GIF_AVATAR))) {
throw new ServiceException(BusiStatus.CANNOT_UPLOAD_GIF);
}
} else if (!avatarUrl.equals(userDb.getAvatar())){
Long price = uploadAvatarService.checkAvatarUrlAndPaid(userDb.getUid(), avatarUrl);
users.setAvatar(null);
YidunCheckUtil.reviewAvatar(users.getUid(), avatarUrl);
isReview = true;
YidunCheckUtil.reviewAvatar(users.getUid(), avatarUrl, RedisKey.user_avatar_under_review.getKey(), price);
}
}
Byte operType = null;

View File

@@ -5,7 +5,6 @@ import com.accompany.business.service.user.UserDetailsService;
import com.accompany.business.vo.user.UserDetailsVo;
import com.accompany.common.annotation.Authorization;
import com.accompany.common.result.BusiResult;
import com.accompany.common.status.BusiStatus;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
@@ -14,11 +13,6 @@ import org.springframework.web.bind.annotation.*;
import static com.accompany.common.constant.ApplicationConstant.PublicParameters.PUB_UID;
/**
* @Author: yangming
* @Date: 2020/4/26 11:14
* @Description: 用户个人详情页查询(包括个人信息和礼物墙以及动态)
**/
@Slf4j
@Api(tags = "用户信息", value = "用户客态详情")
@RestController
@@ -40,11 +34,10 @@ public class UserDetailsController extends BaseController {
@Authorization
@ApiOperation("访问用户主页访客记录")
@GetMapping(value = "/visitUserDetail")
public BusiResult visitUserDetail(@RequestParam("uid") Long uid){
BusiResult busiResult = new BusiResult(BusiStatus.SUCCESS);
public BusiResult<Void> visitUserDetail(@RequestParam("uid") Long uid){
Long selfUid = getUid();
userDetailsService.visitUserDetail(selfUid,uid);
return busiResult;
return BusiResult.success();
}
@Authorization