feat:聊天打通用户体系

This commit is contained in:
dzc committed 2025-11-25 16:54:59 +08:00
1 parent 6a8aed3c96
commit d42089bd33
7 files changed
+99 -21

No files matched your search

@@ -23,11 +23,6 @@ public class ChatCreateOrUpdateUserReqVo {
@Schema(description = "用户手机号")
private String phone;
@Length(min = 5, max = 20, message = "密码长度必须在5-20个字符之间")
@NotEmpty(message = "用户密码不可为空")
@Schema(description = "用户密码")
private String password;
@Length(max = 20, message = "昵称不能大于20字符")
@Schema(description = "用户昵称")
private String nickName;
@@ -29,10 +29,31 @@ public class AppAuthLoginRespVO {
/**
* 仅社交登录、社交绑定时会返回
*
* <p>
* 为什么需要返回?微信公众号、微信小程序支付需要传递 openid 给支付接口
*/
@Schema(description = "社交用户 openid", example = "qq768")
private String openid;
/**
* 聊天令牌
*/
@Schema(description = "聊天令牌")
private ChatToken chatToken;
@Data
static public class ChatToken {
@Schema(description = "每次请求都必须在header中携带accessToken")
private String accessToken;
@Schema(description = "accessToken过期时间(秒)")
private Integer accessTokenExpiresIn;
@Schema(description = "accessToken过期后,通过refreshToken换取新的token")
private String refreshToken;
@Schema(description = "refreshToken过期时间(秒)")
private Integer refreshTokenExpiresIn;
}
}
@@ -6,7 +6,12 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.enums.TerminalEnum;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
import cn.iocoder.yudao.module.member.client.service.ChatApi;
import cn.iocoder.yudao.module.member.client.vo.ChatCreateOrUpdateUserReqVo;
import cn.iocoder.yudao.module.member.client.vo.ChatLoginReqVO;
import cn.iocoder.yudao.module.member.client.vo.ChatLoginRespVo;
import cn.iocoder.yudao.module.member.controller.app.auth.vo.*;
import cn.iocoder.yudao.module.member.convert.auth.AuthConvert;
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
@@ -61,6 +66,8 @@ public class MemberAuthServiceImpl implements MemberAuthService {
private SocialClientApi socialClientApi;
@Resource
private OAuth2TokenApi oauth2TokenApi;
@Resource
private ChatApi chatApi;
@Override
public AppAuthLoginRespVO login(AppAuthLoginReqVO reqVO) {
@@ -230,11 +237,22 @@ public class MemberAuthServiceImpl implements MemberAuthService {
// 当前用户是否已注册
if (userService.getUserByMobile(reqVO.getMobile()) != null) {
// throw exception(USER_REGISTER_MOBILE_USED, reqVO.getMobile());
// 已经注册就登录
MemberUserDO user = userService.createUserIfAbsent(reqVO.getMobile(), userIp, getTerminal());
Assert.notNull(user, "获取用户失败,结果为空");
return createTokenAfterLoginSuccess(user, reqVO.getMobile(), LoginLogTypeEnum.LOGIN_SMS, null);
AppAuthLoginRespVO serviceToken = createTokenAfterLoginSuccess(user, reqVO.getMobile(), LoginLogTypeEnum.LOGIN_SMS, null);
// 同步聊天的用户体系
boolean isSync = userService.syncChatUser(user.getId());
if (isSync) {
ChatLoginReqVO loginObj = new ChatLoginReqVO();
loginObj.setTerminal(1);
loginObj.setUserId(user.getId());
ChatLoginRespVo login = chatApi.login(loginObj);
if (ObjectUtil.isNotEmpty(login)) {
serviceToken.setChatToken(BeanUtils.toBean(login, AppAuthLoginRespVO.ChatToken.class));
}
}
return serviceToken;
}
// 获得获得注册用户
@@ -242,7 +260,21 @@ public class MemberAuthServiceImpl implements MemberAuthService {
Assert.notNull(user, "获取用户失败,结果为空");
// 创建 Token 令牌,记录登录日志
return createTokenAfterLoginSuccess(user, reqVO.getMobile(), LoginLogTypeEnum.LOGIN_SMS, null);
AppAuthLoginRespVO serviceToken = createTokenAfterLoginSuccess(user, reqVO.getMobile(), LoginLogTypeEnum.LOGIN_SMS, null);
// 同步聊天的用户体系
boolean isSync = userService.syncChatUser(user.getId());
if (isSync) {
ChatLoginReqVO loginObj = new ChatLoginReqVO();
loginObj.setTerminal(1);
loginObj.setUserId(user.getId());
ChatLoginRespVo login = chatApi.login(loginObj);
if (ObjectUtil.isNotEmpty(login)) {
serviceToken.setChatToken(BeanUtils.toBean(login, AppAuthLoginRespVO.ChatToken.class));
}
}
return serviceToken;
}
@Override
@@ -91,7 +91,7 @@ public interface MemberUserService {
void updateUser(Long userId, AppMemberUserUpdateReqVO reqVO);
/**
*【会员】修改微信信息
* 【会员】修改微信信息
*/
void updateUserWechat(Long loginUserId, @Valid AppMemberUserWechatUpdateReqVO dto);
@@ -191,4 +191,9 @@ public interface MemberUserService {
* @return 更新结果
*/
boolean updateUserPoint(Long userId, Integer point);
/**
* 同步聊天的用户体系
*/
boolean syncChatUser(Long id);
}
@@ -8,6 +8,8 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.member.client.service.ChatApi;
import cn.iocoder.yudao.module.member.client.vo.ChatCreateOrUpdateUserReqVo;
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserUpdateReqVO;
import cn.iocoder.yudao.module.member.controller.app.user.vo.*;
@@ -72,6 +74,9 @@ public class MemberUserServiceImpl implements MemberUserService {
@Resource
private MemberUserProducer memberUserProducer;
@Resource
private ChatApi chatApi;
@Override
public MemberUserDO getUserByMobile(String mobile) {
return memberUserMapper.selectByMobile(mobile);
@@ -339,4 +344,19 @@ public class MemberUserServiceImpl implements MemberUserService {
return true;
}
@Override
public boolean syncChatUser(Long id) {
// 查询系统用户
MemberUserDO memberUser = memberUserMapper.selectById(id);
if (ObjectUtil.isEmpty(memberUser)) {
return false;
}
ChatCreateOrUpdateUserReqVo chatUser = new ChatCreateOrUpdateUserReqVo();
chatUser.setUserId(memberUser.getId());
chatUser.setUserName(memberUser.getNickname());
chatUser.setPhone(memberUser.getMobile());
chatUser.setNickName(memberUser.getNickname());
chatUser.setAvatar(memberUser.getAvatar());
return chatApi.createOrUpdate(chatUser);
}
}
@@ -229,5 +229,5 @@ pf4j:
chat:
base-url: http://127.0.0.1:8888
api-key: 4H2HkBLygMsxaQKO
app-key: 4H2HkBLygMsxaQKO
app-secret: JIizm84av3TK5xaQdsng7X5mqLPjbeQ0
@@ -171,12 +171,12 @@ debug: false
--- #################### 微信公众号、小程序相关配置 ####################
wx:
mp: # 公众号配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md 文档
# app-id: wx041349c6f39b268b # 测试号(牛希尧提供的)
# secret: 5abee519483bc9f8cb37ce280e814bd0
# app-id: wx041349c6f39b268b # 测试号(牛希尧提供的)
# secret: 5abee519483bc9f8cb37ce280e814bd0
app-id: wx5b23ba7a5589ecbb # 测试号(自己的)
secret: 2a7b3b20c537e52e74afd395eb85f61f
# app-id: wxa69ab825b163be19 # 测试号(Kongdy 提供的)
# secret: bd4f9fab889591b62aeac0d7b8d8b4a0
# app-id: wxa69ab825b163be19 # 测试号(Kongdy 提供的)
# secret: bd4f9fab889591b62aeac0d7b8d8b4a0
# 存储配置,解决 AccessToken 的跨节点的共享
config-storage:
type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取
@@ -185,10 +185,10 @@ wx:
miniapp: # 小程序配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-miniapp-spring-boot-starter/README.md 文档
# appid: wx62056c0d5e8db250 # 测试号(牛希尧提供的)
# secret: 333ae72f41552af1e998fe1f54e1584a
# appid: wx63c280fe3248a3e7 # wenhualian的接口测试号
# secret: 6f270509224a7ae1296bbf1c8cb97aed
# appid: wxc4598c446f8a9cb3 # 测试号(Kongdy 提供的)
# secret: 4a1a04e07f6a4a0751b39c3064a92c8b
# appid: wx63c280fe3248a3e7 # wenhualian的接口测试号
# secret: 6f270509224a7ae1296bbf1c8cb97aed
# appid: wxc4598c446f8a9cb3 # 测试号(Kongdy 提供的)
# secret: 4a1a04e07f6a4a0751b39c3064a92c8b
appid: wx48555e58acd79c3d # 测试号(puhui 提供的)
secret: f0f5fd485bac7f377af6f5ca97636dd4
config-storage:
@@ -246,5 +246,10 @@ justauth:
--- #################### iot相关配置 TODO 芋艿【IOT】:再瞅瞅 ####################
pf4j:
# pluginsDir: /tmp/
pluginsDir: ../plugins
# pluginsDir: /tmp/
pluginsDir: ../plugins
chat:
base-url: http://127.0.0.1:8888
app-key: 4H2HkBLygMsxaQKO
app-secret: JIizm84av3TK5xaQdsng7X5mqLPjbeQ0