3
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace support\OpenImSdk\Core;
|
||||
|
||||
class Config
|
||||
{
|
||||
private static $config = [
|
||||
'host' => 'http://127.0.0.1:10002',
|
||||
'secret' => 'openIM123',
|
||||
];
|
||||
|
||||
/**
|
||||
* 设置配置项
|
||||
* @param array $config
|
||||
* @return void
|
||||
*/
|
||||
public static function setConfig(array $config)
|
||||
{
|
||||
self::$config = array_merge(self::$config, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取密钥
|
||||
* @return string
|
||||
*/
|
||||
public static function getSecret(): string
|
||||
{
|
||||
return self::$config['secret'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取API主机地址
|
||||
* @return string
|
||||
*/
|
||||
public static function getHost(): string
|
||||
{
|
||||
return self::$config['host'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
|
||||
namespace support\OpenImSdk\Core;
|
||||
|
||||
use Exception;
|
||||
|
||||
class TokenManager
|
||||
{
|
||||
/**
|
||||
* 默认Token过期时间(秒)
|
||||
* 仅在API未返回过期时间时使用
|
||||
* @var int
|
||||
*/
|
||||
private $defaultTokenExpire = 86400; // 默认24小时
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置默认Token过期时间
|
||||
* @param int $seconds 过期时间(秒)
|
||||
* @return $this
|
||||
*/
|
||||
public function setDefaultTokenExpire(int $seconds)
|
||||
{
|
||||
$this->defaultTokenExpire = $seconds;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取管理员Token
|
||||
* @param string $userID 管理员ID
|
||||
* @return string|null
|
||||
*/
|
||||
public function getAdminToken(string $userID = 'imAdmin'): ?string
|
||||
{
|
||||
$key = "admin_token_{$userID}";
|
||||
$tokenData = $this->getCache($key);
|
||||
|
||||
if (!$tokenData) {
|
||||
// Token不存在或已过期,需要重新获取
|
||||
return null;
|
||||
}
|
||||
|
||||
$data = json_decode($tokenData, true);
|
||||
return $data['token'] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存管理员Token
|
||||
* @param string $userID 管理员ID
|
||||
* @param string $token Token
|
||||
* @param int|null $expireTimeSeconds Token过期时间(秒)
|
||||
* @return bool
|
||||
*/
|
||||
public function saveAdminToken(string $userID, string $token, ?int $expireTimeSeconds = null): bool
|
||||
{
|
||||
$key = "admin_token_{$userID}";
|
||||
$expireTime = $expireTimeSeconds ?? $this->defaultTokenExpire;
|
||||
|
||||
// 存储token和过期时间
|
||||
$data = [
|
||||
'token' => $token,
|
||||
'expireTimeSeconds' => $expireTime
|
||||
];
|
||||
|
||||
return $this->setCache($key, json_encode($data), $expireTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户Token
|
||||
* @param string $userID 用户ID
|
||||
* @return string|null
|
||||
*/
|
||||
public function getUserToken(string $userID): ?string
|
||||
{
|
||||
$key = "user_token_{$userID}";
|
||||
$tokenData = $this->getCache($key);
|
||||
|
||||
if (!$tokenData) {
|
||||
// Token不存在或已过期,需要重新获取
|
||||
return null;
|
||||
}
|
||||
|
||||
$data = json_decode($tokenData, true);
|
||||
return $data['token'] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存用户Token
|
||||
* @param string $userID 用户ID
|
||||
* @param string $token Token
|
||||
* @param int|null $expireTimeSeconds Token过期时间(秒)
|
||||
* @return bool
|
||||
*/
|
||||
public function saveUserToken(string $userID, string $token, ?int $expireTimeSeconds = null): bool
|
||||
{
|
||||
$key = "user_token_{$userID}";
|
||||
$expireTime = $expireTimeSeconds ?? $this->defaultTokenExpire;
|
||||
|
||||
// 存储token和过期时间
|
||||
$data = [
|
||||
'token' => $token,
|
||||
'expireTimeSeconds' => $expireTime
|
||||
];
|
||||
|
||||
return $this->setCache($key, json_encode($data), $expireTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除Token
|
||||
* @param string $userID 用户ID
|
||||
* @param bool $isAdmin 是否为管理员Token
|
||||
* @return bool
|
||||
*/
|
||||
public function clearToken(string $userID, bool $isAdmin = false): bool
|
||||
{
|
||||
$key = $isAdmin ? "admin_token_{$userID}" : "user_token_{$userID}";
|
||||
return $this->deleteCache($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存
|
||||
* @param string $key 缓存键
|
||||
* @return string|null
|
||||
*/
|
||||
private function getCache(string $key): ?string
|
||||
{
|
||||
return cache($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置缓存
|
||||
* @param string $key 缓存键
|
||||
* @param string $value 缓存值
|
||||
* @param int $expire 过期时间(秒)
|
||||
* @return bool
|
||||
*/
|
||||
private function setCache(string $key, string $value, int $expire): bool
|
||||
{
|
||||
return cache($key,$value,$expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除缓存
|
||||
* @param string $key 缓存键
|
||||
* @return bool
|
||||
*/
|
||||
private function deleteCache(string $key): bool
|
||||
{
|
||||
return cache($key,null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
namespace support\OpenImSdk\Core;
|
||||
|
||||
class Url
|
||||
{
|
||||
// 认证管理
|
||||
static $getAdminToken = '/auth/get_admin_token';
|
||||
static $getUserToken = '/auth/get_user_token';
|
||||
static $forceLogout = '/auth/force_logout';
|
||||
static $parseToken = '/auth/parse_token';
|
||||
static $userToken = '/auth/user_token';
|
||||
|
||||
// 用户管理
|
||||
static $userRegister = '/user/user_register';
|
||||
static $getUsers = '/user/get_users';
|
||||
static $getUsersOnlineStatus = '/user/get_users_online_status';
|
||||
static $getUsersOnlineTokenDetail = '/user/get_users_online_token_detail';
|
||||
static $getSubscribeUsersStatus = '/user/get_subscribe_users_status';
|
||||
static $subscribeUsersStatus = '/user/subscribe_users_status';
|
||||
static $setGlobalMsgRecvOpt = '/user/set_global_msg_recv_opt';
|
||||
static $updateUserInfo = '/user/update_user_info';
|
||||
static $searchNotificationAccount = '/user/search_notification_account';
|
||||
static $addNotificationAccount = '/user/add_notification_account';
|
||||
static $updateNotificationAccount = '/user/update_notification_account';
|
||||
static $accountCheck = '/user/account_check';
|
||||
static $getAllUsersUid = '/user/get_all_users_uid';
|
||||
static $getSelfUserInfo = '/user/get_self_user_info';
|
||||
static $getUsersInfo = '/user/get_users_info';
|
||||
|
||||
// 好友管理
|
||||
static $addBlack = '/friend/add_black';
|
||||
static $addFriend = '/friend/add_friend';
|
||||
static $addFriendResponse = '/friend/add_friend_response';
|
||||
static $deleteFriend = '/friend/delete_friend';
|
||||
static $getBlackList = '/friend/get_black_list';
|
||||
static $getFriendApplyList = '/friend/get_friend_apply_list';
|
||||
static $getFriendList = '/friend/get_friend_list';
|
||||
static $getSelfFriendApplyList = '/friend/get_self_friend_apply_list';
|
||||
static $importFriend = '/friend/import_friend';
|
||||
static $isFriend = '/friend/is_friend';
|
||||
static $removeBlack = '/friend/remove_black';
|
||||
static $setFriendRemark = '/friend/set_friend_remark';
|
||||
static $updateFriends = '/friend/update_friends';
|
||||
|
||||
// 群组管理
|
||||
static $createGroup = '/group/create_group';
|
||||
static $joinGroup = '/group/join_group';
|
||||
static $quitGroup = '/group/quit_group';
|
||||
static $getGroupsInfo = '/group/get_groups_info';
|
||||
static $getGroupMemberList = '/group/get_group_member_list';
|
||||
static $getGroupMembersInfo = '/group/get_group_members_info';
|
||||
static $inviteUserToGroup = '/group/invite_user_to_group';
|
||||
static $kickGroupMember = '/group/kick_group_member';
|
||||
static $transferGroupOwner = '/group/transfer_group_owner';
|
||||
static $getJoinedGroupList = '/group/get_joined_group_list';
|
||||
static $dismissGroup = '/group/dismiss_group';
|
||||
static $muteGroupMember = '/group/mute_group_member';
|
||||
static $cancelMuteGroupMember = '/group/cancel_mute_group_member';
|
||||
static $muteGroup = '/group/mute_group';
|
||||
static $cancelMuteGroup = '/group/cancel_mute_group';
|
||||
static $setGroupMemberNickname = '/group/set_group_member_nickname';
|
||||
static $setGroupMemberInfo = '/group/set_group_member_info';
|
||||
static $getGroupMemberUserIDs = '/group/get_group_member_user_i_ds';
|
||||
static $getGroupAllMemberList = '/group/get_group_all_member_list';
|
||||
static $getUserReqGroupApplicationList = '/group/get_user_req_group_applicationList';
|
||||
static $getGroupUsersReqApplicationList = '/group/get_group_users_req_application_list';
|
||||
static $groupApplicationResponse = '/group/group_application_response';
|
||||
|
||||
// 消息管理
|
||||
static $sendMsg = '/msg/send_msg';
|
||||
static $batchSendMsg = '/msg/batch_send_msg';
|
||||
static $clearMsg = '/msg/clear_msg';
|
||||
static $delMsg = '/msg/del_msg';
|
||||
static $manageSendMsg = '/msg/manage_send_msg';
|
||||
static $revokeMessage = '/msg/revoke_msg';
|
||||
static $sendBusinessNotification = '/msg/send_business_notification';
|
||||
static $getAllConversations = '/msg/get_all_conversations';
|
||||
static $getConversation = '/msg/get_conversation';
|
||||
static $getConversations = '/msg/get_conversations';
|
||||
|
||||
// 会话管理
|
||||
static $getOwnerConversation = '/conversation/get_owner_conversation';
|
||||
static $getSortedConversationList = '/conversation/get_sorted_conversation_list';
|
||||
static $setConversations = '/conversation/set_conversations';
|
||||
|
||||
/**
|
||||
* 构建完整的API URL
|
||||
* @param string $path API路径
|
||||
* @return string 完整URL
|
||||
*/
|
||||
public static function buildUrl(string $path): string
|
||||
{
|
||||
return Config::getHost() . $path;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
<?php
|
||||
|
||||
namespace support\OpenImSdk\Core;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\RequestOptions;
|
||||
use support\OpenImSdk\Exception\ValidatorException;
|
||||
|
||||
class Utils
|
||||
{
|
||||
/**
|
||||
* TokenManager实例
|
||||
* @var TokenManager|null
|
||||
*/
|
||||
private static $tokenManager = null;
|
||||
|
||||
/**
|
||||
* 设置TokenManager
|
||||
* @param TokenManager $tokenManager
|
||||
*/
|
||||
public static function setTokenManager(TokenManager $tokenManager)
|
||||
{
|
||||
self::$tokenManager = $tokenManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取TokenManager
|
||||
* @return TokenManager
|
||||
*/
|
||||
public static function getTokenManager(): TokenManager
|
||||
{
|
||||
if (self::$tokenManager === null) {
|
||||
// 默认使用文件缓存
|
||||
self::$tokenManager = new TokenManager();
|
||||
}
|
||||
|
||||
return self::$tokenManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成操作ID
|
||||
* 用于请求追踪
|
||||
* @return string
|
||||
*/
|
||||
public static function generateOperationID(): string
|
||||
{
|
||||
// 生成一个更具唯一性的操作ID
|
||||
return uniqid('openim_', true) . '_' . str_replace('.', '', microtime(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 发起HTTP请求
|
||||
* @param string $uri 请求URI
|
||||
* @param array $data 请求数据
|
||||
* @param string $token 认证令牌
|
||||
* @return string 响应内容
|
||||
* @throws GuzzleException
|
||||
* @throws ValidatorException
|
||||
*/
|
||||
private static function request(string $uri, array $data, string $token): string
|
||||
{
|
||||
$client = new Client();
|
||||
$options[RequestOptions::JSON] = Validator::validateArray($data);
|
||||
|
||||
// 添加必要的请求头
|
||||
$options[RequestOptions::HEADERS]['operationID'] = self::generateOperationID();
|
||||
|
||||
if ($token) {
|
||||
$options[RequestOptions::HEADERS]['token'] = $token;
|
||||
}
|
||||
|
||||
return $client->post($uri, $options)->getBody()->getContents();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送API请求
|
||||
* @param string $path API路径
|
||||
* @param array $data 请求数据
|
||||
* @param string $errMsg 错误信息
|
||||
* @param string $token 认证令牌
|
||||
* @return array 响应数据
|
||||
*/
|
||||
public static function send(string $path, array $data, string $errMsg, string $token = ''): array|bool
|
||||
{
|
||||
$url = Url::buildUrl($path);
|
||||
//cp($url);
|
||||
$res = json_decode(self::request($url, $data, $token), true);
|
||||
if($res['errCode'] !==0 ){
|
||||
throw new \Exception($res['errMsg'],$res['errCode']);
|
||||
//throw new \Exception($res['errDlt'],$res['errCode']);
|
||||
}
|
||||
if(isset($res['data'])){
|
||||
return $res['data'];
|
||||
}
|
||||
return true;
|
||||
|
||||
try {
|
||||
$url = Url::buildUrl($path);
|
||||
cp($url);
|
||||
return json_decode(self::request($url, $data, $token), true);
|
||||
} catch (GuzzleException $e) {
|
||||
return ['errCode' => $e->getCode(), 'errMsg' => $errMsg, 'errDlt' => $e->getMessage()];
|
||||
} catch (ValidatorException $e) {
|
||||
return ['errCode' => 400, 'errMsg' => $errMsg, 'errDlt' => $e->getMessage()];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取管理员Token
|
||||
* 如果缓存中没有,则自动获取并缓存
|
||||
* @param string $userID 管理员ID
|
||||
* @return string|null
|
||||
*/
|
||||
public static function getAdminToken(string $userID = 'imAdmin'): ?string
|
||||
{
|
||||
$tokenManager = self::getTokenManager();
|
||||
$token = $tokenManager->getAdminToken($userID);
|
||||
|
||||
if (!$token) {
|
||||
// 从服务器获取新的Token
|
||||
$result = self::send(Url::$getAdminToken, [
|
||||
'userID' => $userID,
|
||||
'secret' => Config::getSecret()
|
||||
], '获取管理员Token失败');
|
||||
$token = $result['token'];
|
||||
// 使用API返回的过期时间
|
||||
$expireTimeSeconds = $result['expireTimeSeconds'] ?? null;
|
||||
|
||||
// 保存token,使用API返回的过期时间
|
||||
$tokenManager->saveAdminToken($userID, $token, $expireTimeSeconds);
|
||||
|
||||
}
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户Token
|
||||
* 如果缓存中没有,则自动获取并缓存
|
||||
* @param string $userID 用户ID
|
||||
* @param int $platformID 平台ID
|
||||
* @return string|null
|
||||
*/
|
||||
public static function getUserToken(string $userID, int $platformID = 1): ?string
|
||||
{
|
||||
$tokenManager = self::getTokenManager();
|
||||
$token = $tokenManager->getUserToken($userID);
|
||||
|
||||
if (!$token) {
|
||||
// 从服务器获取新的Token
|
||||
$adminToken = self::getAdminToken();
|
||||
if (!$adminToken) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$result = self::send(Url::$getUserToken, [
|
||||
'userID' => $userID,
|
||||
'platformID' => $platformID
|
||||
], '获取用户Token失败', $adminToken);
|
||||
|
||||
$token = $result['token'];
|
||||
|
||||
// 使用API返回的过期时间
|
||||
$expireTimeSeconds = $result['expireTimeSeconds'] ?? null;
|
||||
|
||||
// 保存token,使用API返回的过期时间
|
||||
$tokenManager->saveUserToken($userID, $token, $expireTimeSeconds);
|
||||
}
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除Token缓存
|
||||
* @param string $userID 用户ID
|
||||
* @param bool $isAdmin 是否为管理员Token
|
||||
* @return bool
|
||||
*/
|
||||
public static function clearToken(string $userID, bool $isAdmin = false): bool
|
||||
{
|
||||
return self::getTokenManager()->clearToken($userID, $isAdmin);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
namespace support\OpenImSdk\Core;
|
||||
|
||||
use support\OpenImSdk\Exception\ValidatorException;
|
||||
|
||||
class Validator
|
||||
{
|
||||
/**
|
||||
* 验证规则
|
||||
* @var string[]
|
||||
*/
|
||||
private static $rules = [
|
||||
'userID' => 'max:64',
|
||||
'userID1' => 'max:64',
|
||||
'userID2' => 'max:64',
|
||||
'ownerUserID' => 'max:64',
|
||||
'friendUserID' => 'max:64',
|
||||
'blackUserID' => 'max:64',
|
||||
'fromUserID' => 'max:64',
|
||||
'toUserID' => 'max:64',
|
||||
'sendID' => 'max:64',
|
||||
'recvID' => 'max:64',
|
||||
'inviterUserID' => 'max:64',
|
||||
'nickname' => 'max:255',
|
||||
'faceURL' => 'max:255',
|
||||
'gender' => 'in:1,2',
|
||||
'groupID' => 'max:64',
|
||||
'groupName' => 'max:255',
|
||||
'introduction' => 'max:255',
|
||||
'notification' => 'max:255',
|
||||
'groupType' => 'in:0,1,2',
|
||||
'oldOwnerUserID' => 'max:64',
|
||||
'newOwnerUserID' => 'max:64',
|
||||
'conversationID' => 'max:128',
|
||||
'handleResult' => 'in:1,2',
|
||||
];
|
||||
|
||||
/**
|
||||
* 验证数组
|
||||
* @param array $data 要验证的数据
|
||||
* @return array 验证后的数据
|
||||
* @throws ValidatorException
|
||||
*/
|
||||
public static function validateArray(array $data): array
|
||||
{
|
||||
foreach ($data as $field => $value) {
|
||||
foreach (self::$rules as $key => $rules) {
|
||||
if ($field == $key) {
|
||||
$ruleList = explode('|', $rules);
|
||||
foreach ($ruleList as $rule) {
|
||||
$ruleParts = explode(':', $rule);
|
||||
$method = $ruleParts[0];
|
||||
$param = $ruleParts[1] ?? null;
|
||||
self::$method($field, $value, $param);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 长度最大验证
|
||||
* @param string $field 字段名
|
||||
* @param mixed $value 字段值
|
||||
* @param int $maxLength 最大长度
|
||||
* @throws ValidatorException
|
||||
*/
|
||||
private static function max(string $field, $value, $maxLength)
|
||||
{
|
||||
if (strlen($value) > (int)$maxLength) {
|
||||
throw new ValidatorException("参数 {$field} 长度不能超过 {$maxLength} 位");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 枚举值验证
|
||||
* @param string $field 字段名
|
||||
* @param mixed $value 字段值
|
||||
* @param string $allowedValues 允许的值(逗号分隔)
|
||||
* @throws ValidatorException
|
||||
*/
|
||||
private static function in(string $field, $value, $allowedValues)
|
||||
{
|
||||
$allowed = explode(',', $allowedValues);
|
||||
if (!in_array($value, $allowed)) {
|
||||
throw new ValidatorException("参数 {$field} 的值必须是以下之一: {$allowedValues},当前值: {$value}");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user