修改回调代码

This commit is contained in:
曹佳豪 2025-07-10 09:27:53 +08:00
parent b09b6f7ece
commit bb812c2bbe
14 changed files with 420 additions and 280 deletions

View File

@ -17,6 +17,12 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import com.wzj.soopin.content.utils.RedisOperator;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.tags.Tag;
import com.wzj.soopin.content.domain.bo.IndexListBO;
import com.wzj.soopin.content.domain.bo.MyListBO;
import com.wzj.soopin.content.domain.bo.SimpleListBO;
import org.springframework.web.bind.annotation.*;
@ -167,23 +173,11 @@ public class VlogController extends BaseInfoProperties {
return R.ok();
}
@GetMapping("indexList")
public R<PagedGridResult> indexList(@RequestParam(defaultValue = "") String userId,
@RequestParam(defaultValue = "") String search,
@RequestParam(defaultValue = "") String cityCode,
@RequestParam(defaultValue = "") String status,
@RequestParam Integer page,
@RequestParam Integer pageSize) {
if (page == null) {
page = COMMON_START_PAGE;
}
if (pageSize == null) {
pageSize = COMMON_PAGE_SIZE;
}
PagedGridResult gridResult = vlogService.getIndexVlogList(userId, search, cityCode,status, page, pageSize);
return R.ok(gridResult);
@Tag(name = "首页视频列表")
@PostMapping("/indexList")
public R<PagedGridResult> indexList(@RequestBody IndexListBO bo, @RequestBody Page page) {
PagedGridResult pages = vlogService.getIndexVlogList(bo, page);
return R.ok(pages);
}
@GetMapping("detail")
@ -219,66 +213,39 @@ public class VlogController extends BaseInfoProperties {
@GetMapping("myPublicList")
public R<PagedGridResult> myPublicList(@RequestParam String userId,
@RequestParam(defaultValue = "") String myId,
@RequestParam Integer page,
@RequestParam Integer pageSize) {
if (page == null) {
page = COMMON_START_PAGE;
}
if (pageSize == null) {
pageSize = COMMON_PAGE_SIZE;
}
PagedGridResult gridResult = vlogService.queryMyVlogList(userId,
myId,
page,
pageSize,
YesOrNo.NO.type);
return R.ok(gridResult);
@Tag(name = "我的公开视频列表")
@PostMapping("/myPublicList")
public R<PagedGridResult> myPublicList(@RequestBody MyListBO bo, @RequestBody Page page) {
PagedGridResult pages = vlogService.queryMyVlogList(bo, page);
return R.ok(pages);
}
@GetMapping("myPrivateList")
public R<PagedGridResult> myPrivateList(@RequestParam String userId,
@RequestParam(defaultValue = "") String myId,
@RequestParam Integer page,
@RequestParam Integer pageSize) {
if (page == null) {
page = COMMON_START_PAGE;
}
if (pageSize == null) {
pageSize = COMMON_PAGE_SIZE;
}
PagedGridResult gridResult = vlogService.queryMyVlogList(userId,
myId,
page,
pageSize,
YesOrNo.YES.type);
return R.ok(gridResult);
@Tag(name = "我的私密视频列表")
@PostMapping("/myPrivateList")
public R<PagedGridResult> myPrivateList(@RequestBody MyListBO bo, @RequestBody Page page) {
PagedGridResult pages = vlogService.queryMyVlogList(bo, page);
return R.ok(pages);
}
@GetMapping("myLikedList")
public R<PagedGridResult> myLikedList(@RequestParam String userId,
@RequestParam(defaultValue = "") String myId,
@RequestParam Integer page,
@RequestParam Integer pageSize) {
@Tag(name = "我点赞的视频列表")
@PostMapping("/myLikedList")
public R<PagedGridResult> myLikedList(@RequestBody MyListBO bo, @RequestBody Page page) {
PagedGridResult pages = vlogService.getMyLikedVlogList(bo, page);
return R.ok(pages);
}
if (page == null) {
page = COMMON_START_PAGE;
}
if (pageSize == null) {
pageSize = COMMON_PAGE_SIZE;
}
@Tag(name = "我关注的视频列表")
@PostMapping("/followList")
public R<PagedGridResult> followList(@RequestBody SimpleListBO bo, @RequestBody Page page) {
PagedGridResult pages = vlogService.getMyFollowVlogList(bo, page);
return R.ok(pages);
}
PagedGridResult gridResult = vlogService.getMyLikedVlogList(userId,
myId,
page,
pageSize);
return R.ok(gridResult);
@Tag(name = "好友视频列表")
@PostMapping("/friendList")
public R<PagedGridResult> friendList(@RequestBody SimpleListBO bo, @RequestBody Page page) {
PagedGridResult pages = vlogService.getMyFriendVlogList(bo, page);
return R.ok(pages);
}
private Integer nacosConuts=0;
@ -336,41 +303,4 @@ public class VlogController extends BaseInfoProperties {
return R.ok(vlogService.getVlogBeLikedCounts(vlogId));
}
@GetMapping("followList")
public R<PagedGridResult> followList(@RequestParam String myId,
@RequestParam Integer page,
@RequestParam Integer pageSize) {
if (page == null) {
page = COMMON_START_PAGE;
}
if (pageSize == null) {
pageSize = COMMON_PAGE_SIZE;
}
PagedGridResult gridResult = vlogService.getMyFollowVlogList(myId,
page,
pageSize);
return R.ok(gridResult);
}
@GetMapping("friendList")
public R<PagedGridResult> friendList(@RequestParam String myId,
@RequestParam Integer page,
@RequestParam Integer pageSize) {
if (page == null) {
page = COMMON_START_PAGE;
}
if (pageSize == null) {
pageSize = COMMON_PAGE_SIZE;
}
PagedGridResult gridResult = vlogService.getMyFriendVlogList(myId,
page,
pageSize);
return R.ok(gridResult);
}
}

View File

@ -29,7 +29,7 @@ import java.util.Collections;
@Slf4j
@Api(tags = "管理端-评论管理接口")
@RequestMapping("admin/comment")
@RequestMapping("/comment")
@RestController
public class CommentController extends BaseController {

View File

@ -28,8 +28,8 @@ import java.time.format.DateTimeFormatter;
import java.time.ZonedDateTime;
@Slf4j
@Api(tags = "管理端-视频上传接口")
@RequestMapping("admin/vlog/upload")
@Api(tags = "管理端-视频")
@RequestMapping("/video")
@RestController
public class VlogUploadController extends BaseInfoProperties {

View File

@ -0,0 +1,23 @@
package com.wzj.soopin.content.domain.bo;
import io.swagger.v3.oas.annotations.media.Schema;
public class IndexListBO {
@Schema(description = "用户ID")
private String userId;
@Schema(description = "搜索关键字")
private String search;
@Schema(description = "城市编码")
private String cityCode;
@Schema(description = "状态")
private String status;
// getter/setter
public String getUserId() { return userId; }
public void setUserId(String userId) { this.userId = userId; }
public String getSearch() { return search; }
public void setSearch(String search) { this.search = search; }
public String getCityCode() { return cityCode; }
public void setCityCode(String cityCode) { this.cityCode = cityCode; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
}

View File

@ -0,0 +1,21 @@
package com.wzj.soopin.content.domain.bo;
import io.swagger.v3.oas.annotations.media.Schema;
public class MyListBO {
@Schema(description = "用户ID")
private String userId;
@Schema(description = "我的ID")
private String myId;
@Schema(description = "是否公开1公开0私密")
private Integer yesOrNo;
// getter/setter
public String getUserId() { return userId; }
public void setUserId(String userId) { this.userId = userId; }
public String getMyId() { return myId; }
public void setMyId(String myId) { this.myId = myId; }
public Integer getYesOrNo() { return yesOrNo; }
public void setYesOrNo(Integer yesOrNo) { this.yesOrNo = yesOrNo; }
}

View File

@ -0,0 +1,11 @@
package com.wzj.soopin.content.domain.bo;
import io.swagger.v3.oas.annotations.media.Schema;
public class SimpleListBO {
@Schema(description = "我的ID")
private String myId;
// getter/setter
public String getMyId() { return myId; }
public void setMyId(String myId) { this.myId = myId; }
}

View File

@ -6,6 +6,9 @@ import com.wzj.soopin.content.domain.bo.VlogBO;
import com.wzj.soopin.content.domain.po.Vlog;
import com.wzj.soopin.content.domain.vo.IndexVlogVO;
import com.wzj.soopin.content.utils.PagedGridResult;
import com.wzj.soopin.content.domain.bo.SimpleListBO;
import com.wzj.soopin.content.domain.bo.MyListBO;
import com.wzj.soopin.content.domain.bo.IndexListBO;
import java.util.List;
import java.util.Map;
@ -28,12 +31,7 @@ public interface VlogService {
/**
* 查询首页/搜索的vlog列表
*/
public PagedGridResult getIndexVlogList(String userId,
String search,
String cityCode,
String status,
Integer page,
Integer pageSize);
public PagedGridResult getIndexVlogList(IndexListBO bo, Page page);
/**
* 根据视频主键查询vlog
@ -53,11 +51,7 @@ public interface VlogService {
/**
* 查询用的公开/私密的视频列表
*/
public PagedGridResult queryMyVlogList(String userId,
String myId,
Integer page,
Integer pageSize,
Integer yesOrNo);
public PagedGridResult queryMyVlogList(MyListBO bo, Page page);
/**
* 用户点赞/喜欢视频
@ -77,24 +71,17 @@ public interface VlogService {
/**
* 查询用户点赞过的短视频
*/
public PagedGridResult getMyLikedVlogList(String userId,
String myId,
Integer page,
Integer pageSize);
public PagedGridResult getMyLikedVlogList(MyListBO bo, Page page);
/**
* 查询用户关注的博主发布的短视频列表
*/
public PagedGridResult getMyFollowVlogList(String myId,
Integer page,
Integer pageSize);
public PagedGridResult getMyFollowVlogList(SimpleListBO bo, Page page);
/**
* 查询朋友发布的短视频列表
*/
public PagedGridResult getMyFriendVlogList(String myId,
Integer page,
Integer pageSize);
public PagedGridResult getMyFriendVlogList(SimpleListBO bo, Page page);
/**
* 根据主键查询vlog

View File

@ -10,6 +10,9 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.wzj.soopin.content.domain.base.BaseInfoProperties;
import com.wzj.soopin.content.domain.bo.VlogBO;
import com.wzj.soopin.content.domain.bo.SimpleListBO;
import com.wzj.soopin.content.domain.bo.MyListBO;
import com.wzj.soopin.content.domain.bo.IndexListBO;
import com.wzj.soopin.content.domain.po.MyLikedVlog;
import com.wzj.soopin.content.domain.po.Vlog;
import com.wzj.soopin.content.domain.po.Users;
@ -135,10 +138,15 @@ public class VlogServiceImpl extends BaseInfoProperties implements VlogService {
}
@Override
public PagedGridResult getIndexVlogList(String userId, String search, String cityCode, String status, Integer page, Integer pageSize) {
Page<Vlog> pageParam = new Page<>(page, pageSize);
public PagedGridResult getIndexVlogList(IndexListBO bo, Page page) {
String userId = bo.getUserId();
String search = bo.getSearch();
String cityCode = bo.getCityCode();
String status = bo.getStatus();
int current = (int) page.getCurrent();
int size = (int) page.getSize();
Page<Vlog> pageParam = new Page<>(current, size);
LambdaQueryWrapper<Vlog> queryWrapper = new LambdaQueryWrapper<>();
if (StringUtils.isNotBlank(search)) {
queryWrapper.like(Vlog::getTitle, search);
}
@ -148,7 +156,6 @@ public class VlogServiceImpl extends BaseInfoProperties implements VlogService {
if (StringUtils.isNotBlank(status)) {
queryWrapper.eq(Vlog::getStatus, status);
}
// Handle blocked videos
if (StringUtils.isNotBlank(userId)) {
String redisKey = REDIS_VIDEO_BLOCK + ":" + userId;
@ -156,7 +163,6 @@ public class VlogServiceImpl extends BaseInfoProperties implements VlogService {
List<String> blockVdList = new ArrayList<>();
ObjectMapper objectMapper = new ObjectMapper();
List<String> reports = redis.lrange(redisKey, 0, -1);
for (String report : reports) {
try {
Map<String, Object> reportMap = objectMapper.readValue(report, new TypeReference<Map<String, Object>>() {});
@ -171,7 +177,6 @@ public class VlogServiceImpl extends BaseInfoProperties implements VlogService {
}
}
}
// Handle blocked users
if (StringUtils.isNotBlank(userId)) {
String redisKey = REDIS_USER_BLOCK + ":" + userId;
@ -179,7 +184,6 @@ public class VlogServiceImpl extends BaseInfoProperties implements VlogService {
List<String> blockUserList = new ArrayList<>();
ObjectMapper objectMapper = new ObjectMapper();
List<String> reports = redis.lrange(redisKey, 0, -1);
for (String report : reports) {
try {
Map<String, Object> reportMap = objectMapper.readValue(report, new TypeReference<Map<String, Object>>() {});
@ -194,24 +198,19 @@ public class VlogServiceImpl extends BaseInfoProperties implements VlogService {
}
}
}
Page<Vlog> vlogPage = vlogMapper.selectPage(pageParam, queryWrapper);
List<Vlog> vlogList = vlogPage.getRecords();
List<IndexVlogVO> voList = vlogList.stream().map(v -> {
IndexVlogVO vo = vlogConvert.toVO(v);
if (StringUtils.isNotBlank(userId)) {
vo.setDoIFollowVloger(fansService.queryDoIFollowVloger(Long.valueOf(userId), Long.valueOf(v.getVlogerId())));
vo.setDoILikeThisVlog(doILikeVlog(userId, v.getId()));
}
vo.setLikeCounts(getVlogBeLikedCounts(v.getId()));
vo.setCommentsCounts(getVlogComment(v.getId()));
return vo;
}).collect(Collectors.toList());
// TODO: 组装PagedGridResult返回
return null;
}
@ -278,29 +277,16 @@ public class VlogServiceImpl extends BaseInfoProperties implements VlogService {
}
@Override
public PagedGridResult queryMyVlogList(String userId, String myId, Integer page, Integer pageSize, Integer yesOrNo) {
Page<Vlog> pageParam = new Page<>(page, pageSize);
public PagedGridResult queryMyVlogList(MyListBO bo, Page page) {
int current = (int) page.getCurrent();
int size = (int) page.getSize();
Page<Vlog> pageParam = new Page<>(current, size);
LambdaQueryWrapper<Vlog> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Vlog::getVlogerId, userId)
.eq(Vlog::getIsPrivate, yesOrNo);
queryWrapper.eq(Vlog::getVlogerId, bo.getUserId())
.eq(Vlog::getIsPrivate, bo.getYesOrNo());
Page<Vlog> vlogPage = vlogMapper.selectPage(pageParam, queryWrapper);
List<Vlog> vlogList = vlogPage.getRecords();
List<IndexVlogVO> voList = vlogList.stream().map(v -> {
IndexVlogVO vo = vlogConvert.toVO(v);
if (StringUtils.isNotBlank(myId)) {
vo.setDoIFollowVloger(fansService.queryDoIFollowVloger(myId, v.getVlogerId()));
vo.setDoILikeThisVlog(doILikeVlog(myId, v.getId()));
}
vo.setLikeCounts(getVlogBeLikedCounts(v.getId()));
vo.setCommentsCounts(getVlogComment(v.getId()));
return vo;
}).collect(Collectors.toList());
// TODO: 组装PagedGridResult返回
return null;
}
@ -378,52 +364,39 @@ public class VlogServiceImpl extends BaseInfoProperties implements VlogService {
}
@Override
public PagedGridResult getMyLikedVlogList(String userId, String myId, Integer page, Integer pageSize) {
Page<MyLikedVlog> pageParam = new Page<>(page, pageSize);
public PagedGridResult getMyLikedVlogList(MyListBO bo, Page page) {
int current = (int) page.getCurrent();
int size = (int) page.getSize();
Page<MyLikedVlog> pageParam = new Page<>(current, size);
LambdaQueryWrapper<MyLikedVlog> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(MyLikedVlog::getUserId, userId);
queryWrapper.eq(MyLikedVlog::getUserId, bo.getUserId());
Page<MyLikedVlog> likedPage = myLikedVlogMapper.selectPage(pageParam, queryWrapper);
List<MyLikedVlog> likedList = likedPage.getRecords();
List<IndexVlogVO> voList = likedList.stream().map(liked -> {
Vlog vlog = vlogMapper.selectById(liked.getVlogId());
if (vlog == null) {
return null;
}
IndexVlogVO vo = vlogConvert.toVO(vlog);
if (StringUtils.isNotBlank(myId)) {
vo.setDoIFollowVloger(fansService.queryDoIFollowVloger(myId, vlog.getVlogerId()));
vo.setDoILikeThisVlog(doILikeVlog(myId, vlog.getId()));
}
vo.setLikeCounts(getVlogBeLikedCounts(vlog.getId()));
vo.setCommentsCounts(getVlogComment(vlog.getId()));
return vo;
}).filter(Objects::nonNull).collect(Collectors.toList());
// TODO: 组装PagedGridResult返回
return null;
}
@Override
public PagedGridResult getMyFollowVlogList(String myId, Integer page, Integer pageSize) {
Page<Vlog> pageParam = new Page<>(page, pageSize);
public PagedGridResult getMyFriendVlogList(SimpleListBO bo, Page page) {
int current = (int) page.getCurrent();
int size = (int) page.getSize();
Page<Vlog> pageParam = new Page<>(current, size);
Map<String, Object> map = new HashMap<>();
map.put("myId", myId);
List<IndexVlogVO> voList = vlogMapperCustom.getMyFollowVlogList(map);
return null;
}
@Override
public PagedGridResult getMyFriendVlogList(String myId, Integer page, Integer pageSize) {
Page<Vlog> pageParam = new Page<>(page, pageSize);
Map<String, Object> map = new HashMap<>();
map.put("myId", myId);
map.put("myId", bo.getMyId());
List<IndexVlogVO> voList = vlogMapperCustom.getMyFriendVlogList(map);
// TODO: 组装PagedGridResult返回
return null;
}
@Override
public PagedGridResult getMyFollowVlogList(SimpleListBO bo, Page page) {
int current = (int) page.getCurrent();
int size = (int) page.getSize();
Page<Vlog> pageParam = new Page<>(current, size);
Map<String, Object> map = new HashMap<>();
map.put("myId", bo.getMyId());
List<IndexVlogVO> voList = vlogMapperCustom.getMyFollowVlogList(map);
// TODO: 组装PagedGridResult返回
return null;
}

View File

@ -8,6 +8,7 @@ import org.dromara.system.domain.event.MessageEvent;
import org.dromara.system.service.IRocketMQService;
import org.dromara.system.service.ITencentIMService;
import org.dromara.system.websocket.MessageWebSocketServer;
import org.dromara.system.service.impl.TencentIMServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.event.EventListener;
@ -125,13 +126,14 @@ public class MessageEventListener {
}
} else {
// 默认为单用户推送
tencentIMSendSuccess = tencentIMService.sendMessageToTencentIM(fromUserId, toUserId, content);
}
if (tencentIMSendSuccess) {
log.info("消息已成功发送到腾讯IM接收者: {}", toUserId);
} else {
log.warn("发送消息到腾讯IM失败将尝试通过其他方式发送");
TencentIMServiceImpl.TencentIMResult imResult = tencentIMService.sendMessageToTencentIM(fromUserId, toUserId, content);
tencentIMSendSuccess = imResult.isSuccess();
if (tencentIMSendSuccess) {
log.info("腾讯IM推送成功userId={}, response={}", toUserId, imResult.getRawResponse());
} else {
log.warn("腾讯IM推送失败userId={}, errorCode={}, errorInfo={}, response={}",
toUserId, imResult.getErrorCode(), imResult.getErrorInfo(), imResult.getRawResponse());
}
}
} catch (Exception e) {
log.error("发送消息到腾讯IM异常将尝试通过其他方式发送", e);

View File

@ -2,6 +2,7 @@ package org.dromara.system.service;
import java.util.List;
import java.util.Map;
import org.dromara.system.service.impl.TencentIMServiceImpl;
/**
* 腾讯IM服务接口
@ -18,7 +19,7 @@ public interface ITencentIMService {
* @param content 消息内容
* @return 是否发送成功
*/
boolean sendMessageToTencentIM(String fromUserId, String toUserId, String content);
TencentIMServiceImpl.TencentIMResult sendMessageToTencentIM(String fromUserId, String toUserId, String content);
/**

View File

@ -149,14 +149,32 @@ public class TencentIMServiceImpl implements ITencentIMService {
return generateUserSig(adminAccount);
}
// 新增结果对象
public static class TencentIMResult {
private boolean success;
private String actionStatus;
private int errorCode;
private String errorInfo;
private String rawResponse;
// getter/setter
public boolean isSuccess() { return success; }
public void setSuccess(boolean success) { this.success = success; }
public String getActionStatus() { return actionStatus; }
public void setActionStatus(String actionStatus) { this.actionStatus = actionStatus; }
public int getErrorCode() { return errorCode; }
public void setErrorCode(int errorCode) { this.errorCode = errorCode; }
public String getErrorInfo() { return errorInfo; }
public void setErrorInfo(String errorInfo) { this.errorInfo = errorInfo; }
public String getRawResponse() { return rawResponse; }
public void setRawResponse(String rawResponse) { this.rawResponse = rawResponse; }
}
@Override
public boolean sendMessageToTencentIM(String fromUserId, String toUserId, String content) {
public TencentIMResult sendMessageToTencentIM(String fromUserId, String toUserId, String content) {
TencentIMResult result = new TencentIMResult();
try {
String userSig = generateAdminUserSig();
String random = String.valueOf(new Random().nextInt(999999999));
// 构建API请求URL
String url = String.format(
"https://console.tim.qq.com/v4/openim/sendmsg" +
"?sdkappid=%s&identifier=%s&usersig=%s&random=%s&contenttype=json",
@ -164,41 +182,34 @@ public class TencentIMServiceImpl implements ITencentIMService {
adminAccount,
userSig,
random);
// 构建消息内容
Map<String, Object> msgContent = new HashMap<>();
msgContent.put("Text", content);
// 构建消息体
Map<String, Object> msgBody = new HashMap<>();
msgBody.put("MsgType", "TIMTextElem");
msgBody.put("MsgContent", msgContent);
// 构建请求体
Map<String, Object> requestBody = new HashMap<>();
requestBody.put("SyncOtherMachine", 2); // 消息不同步至发送方
requestBody.put("SyncOtherMachine", 2);
requestBody.put("From_Account", fromUserId);
requestBody.put("To_Account", toUserId);
requestBody.put("MsgRandom", Integer.parseInt(random));
requestBody.put("MsgBody", new Object[]{msgBody});
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// 发送请求
HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
result.setRawResponse(response.getBody());
log.info("发送消息到腾讯IM结果: {}", response.getBody());
// 解析响应判断是否成功
JSONObject responseJson = new JSONObject(response);
return "OK".equals(responseJson.getStr("ActionStatus"));
cn.hutool.json.JSONObject responseJson = new cn.hutool.json.JSONObject(response.getBody());
result.setActionStatus(responseJson.getStr("ActionStatus"));
result.setErrorCode(responseJson.getInt("ErrorCode", -1));
result.setErrorInfo(responseJson.getStr("ErrorInfo"));
result.setSuccess("OK".equals(result.getActionStatus()) && result.getErrorCode() == 0);
} catch (Exception e) {
log.error("发送消息到腾讯IM异常", e);
return false;
result.setSuccess(false);
result.setErrorInfo(e.getMessage());
}
return result;
}
@Override

View File

@ -25,7 +25,9 @@ import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.redis.utils.RedisUtils;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@RequestMapping("/ums/fans/")
@ -85,67 +87,122 @@ public class FansController {
return R.ok(service.removeById(id));
}
// 提取IM关注处理逻辑为私有方法
private void handleImFollow(Long myId, List<Long> vloggerIds) {
if (myId != null && vloggerIds != null) {
for (Long vloggerId : vloggerIds) {
service.doFollow(myId, vloggerId);
}
}
}
@PostMapping("follow")
public R<Object> follow(@RequestParam Long myId,
@RequestParam Long vloggerId) {
// 判断两个id不能为空
if (myId ==null|| vloggerId==null) {
return R.fail("id不能为空");
public Object follow(@RequestBody(required = false) Map<String, Object> callbackData,
@RequestParam(required = false) Long myId,
@RequestParam(required = false) Long vloggerId) {
// 1. IM回调格式
if (callbackData != null && callbackData.containsKey("CallbackCommand")) {
log.info("收到IM关注回调: {}", callbackData);
String fromAccount = (String) callbackData.get("From_Account");
List<Map<String, String>> followList = (List<Map<String, String>>) callbackData.get("FollowList");
if (fromAccount != null && followList != null) {
Long fromId = Long.valueOf(fromAccount.replace("UserID_", ""));
List<Long> vloggerIds = new java.util.ArrayList<>();
for (Map<String, String> follow : followList) {
String toAccount = follow.get("To_Account");
vloggerIds.add(Long.valueOf(toAccount.replace("UserID_", "")));
}
handleImFollow(fromId, vloggerIds);
log.info("IM回调处理成功: fromId={}, vloggerIds={}", fromId, vloggerIds);
} else {
log.warn("IM回调参数不完整: {}", callbackData);
}
Map<String, Object> resp = new HashMap<>();
resp.put("ActionStatus", "OK");
resp.put("ErrorCode", 0);
resp.put("ErrorInfo", "");
return resp;
}
// 获取拉黑数据
boolean hasblock = memberBlockService.hasBlocked(myId, vloggerId);
if (hasblock) {
return R.fail("已经拉黑");
// 2. 兼容JSON方式传递myId和vloggerId
if (callbackData != null && callbackData.containsKey("myId") && callbackData.containsKey("vloggerId")) {
log.info("收到JSON关注回调: {}", callbackData);
Object myIdObj = callbackData.get("myId");
Object vloggerIdObj = callbackData.get("vloggerId");
if (myIdObj != null && vloggerIdObj != null) {
Long myIdVal = Long.valueOf(myIdObj.toString());
Long vloggerIdVal = Long.valueOf(vloggerIdObj.toString());
handleImFollow(myIdVal, java.util.Arrays.asList(vloggerIdVal));
log.info("JSON回调处理成功: myId={}, vloggerId={}", myIdVal, vloggerIdVal);
return R.ok("关注成功");
} else {
log.warn("JSON回调参数不完整: {}", callbackData);
}
}
// 判断当前用户自己不能关注自己
if (myId ==vloggerId) {
return R.fail("自己不能关注自己");
// 3. 普通参数自动组装成IM格式处理
if (myId != null && vloggerId != null) {
log.info("收到参数关注回调: myId={}, vloggerId={}", myId, vloggerId);
handleImFollow(myId, java.util.Arrays.asList(vloggerId));
log.info("参数回调处理成功: myId={}, vloggerId={}", myId, vloggerId);
return R.ok("关注成功");
}
// 是否已经存在关系
boolean flow = service.queryDoIFollowVloger(myId, vloggerId);
if (flow) {
return R.fail("已经在关注列表里了");
}
// 判断两个id对应的用户是否存在
Member vlogger = memberService.getById(vloggerId);
Member myInfo = memberService.getById(myId);
if (myInfo == null || vlogger == null) {
return R.fail("用户不存在");
}
// 保存粉丝关系到数据库
service.doFollow(myId, vloggerId);
// 博主的粉丝+1我的关注+1
RedisUtils.incrAtomicValue(CacheConstants.MEMBER_FANS + ":" + vloggerId);
RedisUtils.incrAtomicValue(CacheConstants.MEMBER_FOLLOW + ":" + myId);
return R.ok("关注成功");
log.error("关注回调失败,参数为空: callbackData={}, myId={}, vloggerId={}", callbackData, myId, vloggerId);
return R.fail("id不能为空");
}
@PostMapping("cancel")
public R<Object> cancel(@RequestParam Long myId,
@RequestParam Long vloggerId) {
// 判断两个id不能为空
if ( myId==null || vloggerId==null) {
public Object cancel(@RequestBody(required = false) Map<String, Object> callbackData,
@RequestParam(required = false) Long myId,
@RequestParam(required = false) Long vloggerId) {
// 1. 判断是否为IM回调格式
if (callbackData != null && callbackData.containsKey("CallbackCommand")) {
log.info("收到IM取消关注回调: {}", callbackData);
String fromAccount = (String) callbackData.get("From_Account");
List<String> toAccounts = null;
// 兼容腾讯IM的 To_Account 可能是 List<String> List<Map<String, String>>
Object toAccountObj = callbackData.get("To_Account");
if (toAccountObj instanceof List) {
List<?> list = (List<?>) toAccountObj;
if (!list.isEmpty() && list.get(0) instanceof String) {
toAccounts = (List<String>) list;
} else if (!list.isEmpty() && list.get(0) instanceof Map) {
// 兼容部分IM平台格式
toAccounts = new java.util.ArrayList<>();
for (Object obj : list) {
Map<?, ?> map = (Map<?, ?>) obj;
Object acc = map.get("To_Account");
if (acc != null) toAccounts.add(acc.toString());
}
}
}
if (fromAccount != null && toAccounts != null) {
Long fromId = Long.valueOf(fromAccount.replace("UserID_", ""));
for (String toAccount : toAccounts) {
Long toId = Long.valueOf(toAccount.replace("UserID_", ""));
service.doCancel(fromId, toId);
}
log.info("IM取消关注回调处理成功: fromId={}, toAccounts={}", fromId, toAccounts);
} else {
log.warn("IM取消关注回调参数不完整: {}", callbackData);
}
// 返回IM平台要求的应答
Map<String, Object> resp = new HashMap<>();
resp.put("ActionStatus", "OK");
resp.put("ErrorCode", 0);
resp.put("ErrorInfo", "");
return resp;
}
// 2. 原有取关逻辑
if (myId == null || vloggerId == null) {
return R.fail("id不能为空");
}
// 是否已经存在关系
boolean flow = service.queryDoIFollowVloger(myId, vloggerId);
if (!flow) {
return R.fail("没有关注信息");
}
// 删除业务的执行
service.doCancel(myId, vloggerId);
// 博主的粉丝-1我的关注-1
RedisUtils.decrAtomicValue(CacheConstants.MEMBER_FANS + ":" + vloggerId);
RedisUtils.decrAtomicValue(CacheConstants.MEMBER_FOLLOW + ":" + myId);
return R.ok("取消成功");
}

View File

@ -22,6 +22,10 @@ import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import lombok.extern.slf4j.Slf4j;
/**
* 会员信息Controller
*
@ -31,6 +35,7 @@ import java.util.List;
@Tag(name = "会员信息接口列表")
@RequestMapping("/ums/member/")
@RestController
@Slf4j
public class MemberController extends BaseController {
@Autowired
private IMemberService service;
@ -76,8 +81,120 @@ public class MemberController extends BaseController {
@SaCheckPermission("ums:member:edit")
@Log(title = "会员信息", businessType = BusinessType.UPDATE)
@PostMapping("update")
public R edit(@RequestBody MemberBO member) {
return R.ok(service.updateById(convert.toPo(member)));
public Object edit(@RequestBody(required = false) Map<String, Object> callbackData,
@RequestParam(required = false) Long id,
@RequestParam(required = false) String nickname,
@RequestParam(required = false) Integer gender) {
// 1. IM回调格式 - 用户资料更新回调
if (callbackData != null && callbackData.containsKey("CallbackCommand")) {
log.info("收到IM用户资料更新回调: {}", callbackData);
String callbackCommand = (String) callbackData.get("CallbackCommand");
if ("Profile.CallbackPortraitSet".equals(callbackCommand)) {
String fromAccount = (String) callbackData.get("From_Account");
List<Map<String, Object>> profileItems = (List<Map<String, Object>>) callbackData.get("ProfileItem");
if (fromAccount != null && profileItems != null) {
Long userId = Long.valueOf(fromAccount.replace("UserID_", ""));
// 根据 ProfileItem 更新用户资料
Member memberToUpdate = service.getById(userId);
if (memberToUpdate != null) {
for (Map<String, Object> item : profileItems) {
String tag = (String) item.get("Tag");
Object value = item.get("Value");
updateMemberProfile(memberToUpdate, tag, value);
}
service.updateById(memberToUpdate);
log.info("IM用户资料更新回调处理成功: userId={}, profileItems={}", userId, profileItems);
} else {
log.warn("IM用户资料更新回调中用户不存在: userId={}", userId);
}
} else {
log.warn("IM用户资料更新回调参数不完整: {}", callbackData);
}
// 返回IM平台要求的应答
Map<String, Object> resp = new HashMap<>();
resp.put("ActionStatus", "OK");
resp.put("ErrorCode", 0);
resp.put("ErrorInfo", "");
return resp;
}
}
// 2. 兼容JSON方式传递参数
if (callbackData != null && callbackData.containsKey("id")) {
log.info("收到JSON会员更新回调: {}", callbackData);
Object idObj = callbackData.get("id");
Object nicknameObj = callbackData.get("nickname");
Object genderObj = callbackData.get("gender");
if (idObj != null) {
Long memberId = Long.valueOf(idObj.toString());
Member memberToUpdate = service.getById(memberId);
if (memberToUpdate != null) {
if (nicknameObj != null) {
memberToUpdate.setNickname(nicknameObj.toString());
}
if (genderObj != null) {
memberToUpdate.setGender(Integer.valueOf(genderObj.toString()));
}
service.updateById(memberToUpdate);
log.info("JSON会员更新回调处理成功: id={}, nickname={}, gender={}", memberId, nicknameObj, genderObj);
return R.ok("更新成功");
} else {
log.warn("JSON会员更新回调中用户不存在: id={}", memberId);
}
}
}
// 3. 普通参数更新
if (id != null) {
log.info("收到参数会员更新回调: id={}, nickname={}, gender={}", id, nickname, gender);
Member memberToUpdate = service.getById(id);
if (memberToUpdate != null) {
if (nickname != null) {
memberToUpdate.setNickname(nickname);
}
if (gender != null) {
memberToUpdate.setGender(gender);
}
service.updateById(memberToUpdate);
log.info("参数会员更新回调处理成功: id={}, nickname={}, gender={}", id, nickname, gender);
return R.ok("更新成功");
} else {
log.warn("参数会员更新回调中用户不存在: id={}", id);
}
}
log.error("会员信息更新失败,参数为空: callbackData={}, id={}, nickname={}, gender={}", callbackData, id, nickname, gender);
return R.fail("参数不能为空");
}
/**
* 根据IM回调的ProfileItem更新用户资料
*/
private void updateMemberProfile(Member member, String tag, Object value) {
if (tag == null || value == null) {
return;
}
switch (tag) {
case "Tag_Profile_IM_Nick":
member.setNickname(value.toString());
break;
case "Tag_Profile_IM_Gender":
// 根据性别值设置性别字段
if ("Gender_Type_Male".equals(value)) {
member.setGender(1); //
} else if ("Gender_Type_Female".equals(value)) {
member.setGender(2); //
} else {
member.setGender(0); // 未知
}
break;
case "Tag_Profile_IM_AllowType":
// 处理好友验证方式
break;
case "Tag_Profile_Custom_Data":
// 处理自定义数据
break;
default:
log.debug("未处理的用户资料字段: tag={}, value={}", tag, value);
break;
}
}
@Tag(name ="修改会员备注信息")

View File

@ -97,14 +97,21 @@ public class FansServiceImpl extends ServiceImpl<FansMapper, Fans> implements IF
if (fan != null && YesOrNo.YES.type.equals(fan.getFriendFlag())) {
// 抹除双方的朋友关系自己的关系删除即可
Fans pendingFan = queryFansRelationship(vloggerId, myId);
pendingFan.setBothFriend(YesOrNo.NO.type);
baseMapper.updateById(pendingFan);
if (pendingFan != null) {
pendingFan.setBothFriend(YesOrNo.NO.type);
baseMapper.updateById(pendingFan);
} else {
log.warn("取消关注时未找到对方的粉丝关系myId={}, vloggerId={}", vloggerId, myId);
}
}
// 删除自己的关注关联表记录
LambdaQueryWrapper<Fans> deleteWrapper = new LambdaQueryWrapper<>();
deleteWrapper.eq(Fans::getId, fan.getId());
baseMapper.delete(deleteWrapper);
if (fan != null) {
LambdaQueryWrapper<Fans> deleteWrapper = new LambdaQueryWrapper<>();
deleteWrapper.eq(Fans::getId, fan.getId());
baseMapper.delete(deleteWrapper);
} else {
log.warn("取消关注时未找到自己的粉丝关系myId={}, vloggerId={}", myId, vloggerId);
}
// 推送取关消息
Member follower = memberService.getById(myId);
Member vlogger = memberService.getById(vloggerId);