提交
This commit is contained in:
@@ -2,19 +2,25 @@ package com.ruoyi.oa.im;
|
||||
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.common.helper.LoginHelper;
|
||||
import com.ruoyi.oa.im.mapper.ImBindMapper;
|
||||
import com.ruoyi.system.mapper.SysUserMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 当前用户的 IM 凭据(供 Web SDK 登录)
|
||||
* 当前用户的 IM 凭据。
|
||||
* 没有绑定时自动给当前 OA 用户注册一个 IM 账号(imUserId = "oa_{userId}"),手机号不再是必须。
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/system/user/im")
|
||||
@@ -23,17 +29,30 @@ public class ImCredentialsController extends BaseController {
|
||||
private final ImBindMapper bindMapper;
|
||||
private final OpenImClient openImClient;
|
||||
private final OpenImProperties props;
|
||||
private final SysUserMapper userMapper;
|
||||
|
||||
/** 当前用户 IM 登录所需信息:imUserId + token + apiUrl + wsUrl */
|
||||
/**
|
||||
* 获取当前用户 IM 登录所需信息。
|
||||
* @param platformId 1=iOS 2=Android 3=Windows 4=OSX 5=Web;默认 5
|
||||
*/
|
||||
@GetMapping("/credentials")
|
||||
public R<Map<String, Object>> credentials() {
|
||||
public R<Map<String, Object>> credentials(
|
||||
@RequestParam(value = "platformId", required = false, defaultValue = "5") int platformId) {
|
||||
Long userId = LoginHelper.getUserId();
|
||||
ImBind bind = bindMapper.selectById(userId);
|
||||
if (bind == null || bind.getImUserId() == null) {
|
||||
return R.fail("当前账号未绑定 IM");
|
||||
if (userId == null) {
|
||||
return R.fail("未登录");
|
||||
}
|
||||
// platformId=5: Web
|
||||
String token = openImClient.issueUserToken(bind.getImUserId(), 5);
|
||||
|
||||
ImBind bind = bindMapper.selectById(userId);
|
||||
if (bind == null || bind.getImUserId() == null || bind.getImUserId().isEmpty()) {
|
||||
// 自动注册:不再要求手机号
|
||||
bind = ensureBind(userId);
|
||||
if (bind == null) {
|
||||
return R.fail("IM 账号注册失败");
|
||||
}
|
||||
}
|
||||
|
||||
String token = openImClient.issueUserToken(bind.getImUserId(), platformId);
|
||||
if (token == null) {
|
||||
return R.fail("获取 IM token 失败");
|
||||
}
|
||||
@@ -44,4 +63,29 @@ public class ImCredentialsController extends BaseController {
|
||||
data.put("wsUrl", props.getWsUrl());
|
||||
return R.ok(data);
|
||||
}
|
||||
|
||||
/** 给指定 OA userId 在 OpenIM 主 API 直接注册一个账号并落 bind 表 */
|
||||
private ImBind ensureBind(Long oaUserId) {
|
||||
SysUser u = userMapper.selectById(oaUserId);
|
||||
if (u == null) return null;
|
||||
String nickname = u.getNickName() != null && !u.getNickName().isEmpty()
|
||||
? u.getNickName()
|
||||
: (u.getUserName() != null ? u.getUserName() : ("user" + oaUserId));
|
||||
String imUserId = "oa_" + oaUserId;
|
||||
|
||||
boolean ok = openImClient.registerImUserDirect(imUserId, nickname);
|
||||
if (!ok) {
|
||||
log.warn("[IM] registerImUserDirect failed for OA user {}", oaUserId);
|
||||
return null;
|
||||
}
|
||||
|
||||
ImBind bind = new ImBind();
|
||||
bind.setUserId(oaUserId);
|
||||
bind.setPhone(u.getPhonenumber());
|
||||
bind.setImUserId(imUserId);
|
||||
bind.setBindStatus(1);
|
||||
bindMapper.insert(bind);
|
||||
log.info("[IM] auto-bound OA {} -> IM {}", oaUserId, imUserId);
|
||||
return bind;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,6 +205,39 @@ public class OpenImClient {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接在 OpenIM 主 API 注册账号(无需手机号、无需 chat 层)。
|
||||
* 用于给 OA 内部账号(如 admin / 后台账号)建立 IM 账号。
|
||||
*
|
||||
* @param imUserId 业务侧自定义的 IM userID(建议格式 "oa_{oaUserId}")
|
||||
* @param nickname 昵称
|
||||
* @return true 注册成功或已存在;false 失败
|
||||
*/
|
||||
public boolean registerImUserDirect(String imUserId, String nickname) {
|
||||
if (!props.isEnabled()) { return false; }
|
||||
Map<String, Object> user = new HashMap<>();
|
||||
user.put("userID", imUserId);
|
||||
user.put("nickname", nickname == null || nickname.isEmpty() ? imUserId : nickname);
|
||||
user.put("faceURL", "");
|
||||
|
||||
Map<String, Object> body = new HashMap<>();
|
||||
body.put("secret", props.getSecret());
|
||||
body.put("users", java.util.Collections.singletonList(user));
|
||||
|
||||
JSONObject resp = postJson(props.getApiUrl() + "/user/user_register", body, getAdminToken());
|
||||
Integer errCode = resp.getInteger("errCode");
|
||||
if (errCode != null && errCode == 0) {
|
||||
return true;
|
||||
}
|
||||
// 已存在通常 errCode 1102 或 20004,视为成功
|
||||
if (errCode != null && (errCode == 1102 || errCode == 20004)) {
|
||||
log.debug("[OpenIM] imUser {} already exists, ok", imUserId);
|
||||
return true;
|
||||
}
|
||||
log.warn("[OpenIM] registerImUserDirect failed for {}: {}", imUserId, resp);
|
||||
return false;
|
||||
}
|
||||
|
||||
private static String md5(String text) {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
|
||||
Reference in New Issue
Block a user