diff --git a/ruoyi-common/ruoyi-common-mq/src/main/java/org/dromara/common/mq/domain/MemberCreateEvent.java b/ruoyi-common/ruoyi-common-mq/src/main/java/org/dromara/common/mq/domain/MemberCreateEvent.java new file mode 100644 index 000000000..e36529509 --- /dev/null +++ b/ruoyi-common/ruoyi-common-mq/src/main/java/org/dromara/common/mq/domain/MemberCreateEvent.java @@ -0,0 +1,20 @@ +package org.dromara.common.mq.domain; + +import lombok.AllArgsConstructor; +import lombok.Data; +import org.springframework.context.ApplicationEvent; + +import java.time.Clock; + +/** + * 会员创建事件 + */ +public class MemberCreateEvent extends ApplicationEvent { + public MemberCreateEvent(Object source) { + super(source); + } + + public MemberCreateEvent(Object source, Clock clock) { + super(source, clock); + } +} diff --git a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/domain/po/Member.java b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/domain/po/Member.java index 62ea42046..7d264f6e7 100644 --- a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/domain/po/Member.java +++ b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/domain/po/Member.java @@ -101,5 +101,7 @@ public class Member extends BaseAudit { @Schema(description ="用户id") private Long userId; + @Schema(description = "角色") + private String role; } diff --git a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/enums/MemberRoleEnum.java b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/enums/MemberRoleEnum.java new file mode 100644 index 000000000..172a5274f --- /dev/null +++ b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/enums/MemberRoleEnum.java @@ -0,0 +1,56 @@ +package com.wzj.soopin.member.enums; + +/** + * 会员角色枚举 + */ +public enum MemberRoleEnum { + /** + * 租户管理员 + */ + TENANT_ADMIN("tenantAdmin"), + /** + * 租户普通用户 + */ + TENANT_USER("tenantUser"), + /** + * 租户访客 + */ + TENANT_GUEST("tenantGuest"), + /** + * 租户所有者 + */ + TENANT_OWNER("tenantOwner"), + /** + * 系统管理员 + */ + SYSTEM_ADMIN("systemAdmin"), + /** + * 系统普通用户 + */ + SYSTEM_USER("systemUser"), + /** + * 普通用户 + */ + COMMON_USER("commonUser"); + /** + * 角色 + */ + private final String role; + + MemberRoleEnum(String role) { + this.role = role; + } + + public String getRole() { + return role; + } + + public static MemberRoleEnum getByRole(String role) { + for (MemberRoleEnum memberRoleEnum : MemberRoleEnum.values()) { + if (memberRoleEnum.getRole().equals(role)) { + return memberRoleEnum; + } + } + return null; + } +} diff --git a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/listener/MemberCreateEventListener.java b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/listener/MemberCreateEventListener.java new file mode 100644 index 000000000..05803edb0 --- /dev/null +++ b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/listener/MemberCreateEventListener.java @@ -0,0 +1,86 @@ +package com.wzj.soopin.member.listener; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.wzj.soopin.member.domain.po.Member; +import com.wzj.soopin.member.service.IMemberService; +import com.wzj.soopin.member.service.ITencentIMServicce; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.mq.domain.MemberCreateEvent; +import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; + +/** + * 消息事件监听器 + * + * @author ruoyi + */ +@Slf4j +@Component +@AllArgsConstructor +public class MemberCreateEventListener { + + + private final IMemberService memberService; + + private final ITencentIMServicce tencentIMService; + + + /** + * 处理消息事件 + */ + @Async + @EventListener + @Transactional(rollbackFor = Exception.class) + public void handleMessageEvent(MemberCreateEvent event) { + try { + // 提取消息和用户ID + Map userMap = (Map)event.getSource(); + + List memberList = memberService.list(new LambdaQueryWrapper() + .eq(Member::getPhoneEncrypted, (String) userMap.get("phonenumber")) + ); + + //如果存在则绑定 + //如果不存在则创建 + if (!memberList.isEmpty()) { + //绑定 + Member member = memberList.get(0); + member.setUserId((Long) userMap.get("userId")); + member.setRole(userMap.get("role").toString()); + memberService.updateById(member); + //设置im账号为管理员 + tencentIMService.updateMemberRole(member); + } else { + //创建 + Member member=new Member(); + member.setNickname((String) userMap.get("nickName")); + member.setPassword((String) userMap.get("password")); + member.setPhoneHidden((String) userMap.get("phonenumber")); + member.setAvatar((String) userMap.get("avatar")); + member.setGender((Integer) userMap.get("sex")); + member.setRole(userMap.get("role").toString()); + member.setUserId((Long) userMap.get("userId")); + //创建im账号 + String userSig=tencentIMService.createTencentIMAccount(member); + + member.setUserSig(userSig); + memberService.save(member); + + + //设置im账号为管理员 + tencentIMService.updateMemberRole(member); + + + } + + } catch (Exception e) { + log.error("处理消息事件失败", e); + } + } +} diff --git a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/ITencentIMServicce.java b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/ITencentIMServicce.java index aa596e136..bbb20843b 100644 --- a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/ITencentIMServicce.java +++ b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/ITencentIMServicce.java @@ -9,4 +9,5 @@ import com.wzj.soopin.member.domain.po.Member; */ public interface ITencentIMServicce { String createTencentIMAccount(Member member); + void updateMemberRole(Member member); } diff --git a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/impl/TencentIMServiceImpl.java b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/impl/TencentIMServiceImpl.java index 006bbe7ca..787600082 100644 --- a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/impl/TencentIMServiceImpl.java +++ b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/impl/TencentIMServiceImpl.java @@ -1,5 +1,6 @@ package com.wzj.soopin.member.service.impl; +import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; import com.wzj.soopin.member.domain.po.Member; import com.wzj.soopin.member.service.ITencentIMServicce; @@ -90,6 +91,79 @@ public class TencentIMServiceImpl implements ITencentIMServicce { } } + + /** + * 更新用户角色 + */ + @Override + public void updateMemberRole(Member member) { + //调用腾讯云IM接口更新用户角色 + + String phone=member.getPhoneHidden(); + try { + + //这里生成一个管理员签名, + String adminSig=generateUserSig(adminAccount); + String random = String.valueOf(System.currentTimeMillis()); + + JSONObject object=new JSONObject(); + object.put("Tag","Tag_Profile_IM_Role"); + object.put("Value",member.getRole()); + + JSONArray jsonArray = new JSONArray(); + jsonArray.add(object); + // 构建请求体 + JSONObject requestBody = new JSONObject(); + requestBody.put("From_Account", member.getId()+""); + requestBody.put("ProfileItem", jsonArray); + + // 构建URL - 使用管理员账号(administrator)而不是用户ID来生成签名 + String urlString = String.format( + "https://console.tim.qq.com/v4/profile/protrait_set" + + "?sdkappid=%s&identifier=%s&usersig=%s&random=%s&contenttype=json", + GenerateTestUserSig.SDKAPPID, + adminAccount, // 使用管理员账号 + adminSig, // 使用管理员的UserSig + random); +// return userSig; + + // 创建HTTP客户端 + OkHttpClient client = new OkHttpClient().newBuilder().connectTimeout(15, TimeUnit.SECONDS) + .readTimeout(15, TimeUnit.SECONDS) + .writeTimeout(15, TimeUnit.SECONDS) + .build(); + + // 发送请求 + Request request = new Request.Builder() + .url(urlString) + .post(RequestBody.create(MediaType.get("application/json; charset=utf-8"), + requestBody.toString())) + .build(); + + try (Response response = client.newCall(request).execute()) { + if (!response.isSuccessful()) { + log.error("更新IM账号角色失败: {}, 状态码: {}",phone , response.code()); + throw new ServiceException(String.format("创建IM账号异常: %s", phone)); + } + + String responseBody = response.body().string(); + JSONObject jsonResponse = new JSONObject(responseBody); + int errorCode = jsonResponse.getInt("ErrorCode"); + + if (errorCode == 0) { + log.info("更新IM账号角色成功: {}", phone); + } else { + log.error("更新IM账号角色失败: {}, 错误码: {}, 错误信息: {}", + phone, errorCode, jsonResponse.get("ErrorInfo")); + throw new ServiceException(String.format("更新IM账号角色异常: %s", phone)); + + } + } + } catch (Exception e) { + throw new ServiceException(String.format("更新IM账号角色异常: %s", phone)); + } + } + /** * 生成UserSig */ diff --git a/ruoyi-modules/ruoyi-system/pom.xml b/ruoyi-modules/ruoyi-system/pom.xml index 5f4e5edf2..90c7200d4 100644 --- a/ruoyi-modules/ruoyi-system/pom.xml +++ b/ruoyi-modules/ruoyi-system/pom.xml @@ -31,11 +31,14 @@ org.dromara ruoyi-common-job + + org.dromara + ruoyi-common-mq + org.dromara ruoyi-common-mybatis - org.dromara ruoyi-common-translation diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserBo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserBo.java index 1472d2428..8fd88b9a3 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserBo.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserBo.java @@ -113,6 +113,11 @@ public class SysUserBo extends BaseEntity { */ private String excludeUserIds; + /** + * 同步会员 + */ + private String syncMemberFlag; + public SysUserBo(Long userId) { this.userId = userId; } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java index c1e2741bb..498c616ae 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java @@ -5,10 +5,12 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONObject; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.RequiredArgsConstructor; @@ -19,6 +21,7 @@ import org.dromara.common.core.domain.dto.UserDTO; import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.service.UserService; import org.dromara.common.core.utils.*; +import org.dromara.common.mq.domain.MemberCreateEvent; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.satoken.utils.LoginHelper; @@ -32,13 +35,11 @@ import org.dromara.system.mapper.*; import org.dromara.system.service.ISysUserService; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; //import com.wzj.soopin.member.domain.po.Member; @@ -61,6 +62,7 @@ public class SysUserServiceImpl implements ISysUserService, UserService { private final SysPostMapper postMapper; private final SysUserRoleMapper userRoleMapper; private final SysUserPostMapper userPostMapper; + private final ApplicationEventPublisher eventPublisher; @Override public TableDataInfo selectPageUserList(SysUserBo user, PageQuery pageQuery) { @@ -309,9 +311,37 @@ public class SysUserServiceImpl implements ISysUserService, UserService { int rows = baseMapper.insert(sysUser); user.setUserId(sysUser.getUserId()); // 新增用户岗位关联 - insertUserPost(user, false); + + + + + // 新增用户与角色管理 insertUserRole(user, false); + + // 新增用户会员关联 + if(user.getSyncMemberFlag()!=null&&user.getSyncMemberFlag().equals(SystemConstants.NORMAL)){ + Map source=new HashMap<>(); + source.put("userId",user.getUserId()); + source.put("userName",sysUser.getUserName()); + source.put("nickName",sysUser.getNickName()); + source.put("email",sysUser.getEmail()); + source.put("phonenumber",sysUser.getPhonenumber()); + source.put("avatar", sysUser.getAvatar()); + source.put("password",sysUser.getPassword()); + source.put("set",sysUser.getSex()); + //获取用户角色id + LambdaQueryWrapper roleQueryWrapper = new LambdaQueryWrapper(); + roleQueryWrapper.in(SysRole::getRoleId,user.getRoleIds()); + List roles = roleMapper.selectRoleList(roleQueryWrapper); + if(CollectionUtils.isNotEmpty(roles)){ + List roleKeys= roles.stream().map(SysRoleVo::getRoleKey).collect(Collectors.toList()); + source.put("roleKeys",String.join(",",roleKeys)); + } + eventPublisher.publishEvent(new MemberCreateEvent(source)); + } + + return rows; }