Merge branch 'main' of github.com:gzydong/hyperf-chat into main

* 'main' of github.com:gzydong/hyperf-chat:
  初始化
  初始化
main
gzydong 2020-12-03 19:49:34 +08:00
commit 81b381ee5f
15 changed files with 146 additions and 53 deletions

View File

@ -2,24 +2,24 @@
namespace App\Constants; namespace App\Constants;
use Hyperf\Constants\AbstractConstants;
use Hyperf\Constants\Annotation\Constants;
/** /**
* @Constants * HTTP 响应状态码枚举
*
* Class ResponseCode
* @package App\Constants
*/ */
class ResponseCode extends AbstractConstants class ResponseCode
{ {
const SUCCESS = 200; // 接口处理成功 const SUCCESS = 200; // 接口处理成功
const FAIL = 305; // 接口处理失败 const FAIL = 305; // 接口处理失败
/** /**
* @Message("Server Error") * Server Error
*/ */
const SERVER_ERROR = 500; const SERVER_ERROR = 500;
/** /**
* @Message("请求数据验证失败!") * 请求数据验证失败!
*/ */
const VALIDATION_ERROR = 301; const VALIDATION_ERROR = 301;
} }

View File

@ -39,4 +39,18 @@ class SocketConstants
* WebSocket 消息消费队列交换机名称 * WebSocket 消息消费队列交换机名称
*/ */
const CONSUMER_MESSAGE_EXCHANGE = 'im.message.fanout'; const CONSUMER_MESSAGE_EXCHANGE = 'im.message.fanout';
/**
* @return array
*/
public static function getMap(): array
{
return [
self::EVENT_TALK => '对话消息通知',
self::EVENT_KEYBOARD => '键盘输入事件通知',
self::EVENT_ONLINE_STATUS => '用户在线状态通知',
self::EVENT_REVOKE_TALK => '聊天消息撤销通知',
self::EVENT_FRIEND_APPLY => '好友申请消息通知'
];
}
} }

View File

@ -1,5 +1,4 @@
<?php <?php
declare(strict_types=1);
namespace App\Controller\Api\V1; namespace App\Controller\Api\V1;

View File

@ -16,6 +16,7 @@ use App\Model\Group\UsersGroupNotice;
use App\Amqp\Producer\ChatMessageProducer; use App\Amqp\Producer\ChatMessageProducer;
use App\Service\SocketRoomService; use App\Service\SocketRoomService;
use App\Service\GroupService; use App\Service\GroupService;
use App\Constants\SocketConstants;
/** /**
* Class GroupController * Class GroupController
@ -81,7 +82,7 @@ class GroupController extends CController
// ...消息推送队列 // ...消息推送队列
$this->producer->produce( $this->producer->produce(
new ChatMessageProducer('event_talk', [ new ChatMessageProducer(SocketConstants::EVENT_TALK, [
'sender' => $user_id, //发送者ID 'sender' => $user_id, //发送者ID
'receive' => intval($data['group_id']), //接收者ID 'receive' => intval($data['group_id']), //接收者ID
'source' => 2, //接收者类型 1:好友;2:群组 'source' => 2, //接收者类型 1:好友;2:群组
@ -146,7 +147,7 @@ class GroupController extends CController
// ...消息推送队列 // ...消息推送队列
$this->producer->produce( $this->producer->produce(
new ChatMessageProducer('event_talk', [ new ChatMessageProducer(SocketConstants::EVENT_TALK, [
'sender' => $user_id, //发送者ID 'sender' => $user_id, //发送者ID
'receive' => intval($params['group_id']), //接收者ID 'receive' => intval($params['group_id']), //接收者ID
'source' => 2, //接收者类型 1:好友;2:群组 'source' => 2, //接收者类型 1:好友;2:群组
@ -180,7 +181,7 @@ class GroupController extends CController
// ...消息推送队列 // ...消息推送队列
$this->producer->produce( $this->producer->produce(
new ChatMessageProducer('event_talk', [ new ChatMessageProducer(SocketConstants::EVENT_TALK, [
'sender' => $user_id, //发送者ID 'sender' => $user_id, //发送者ID
'receive' => intval($params['group_id']), //接收者ID 'receive' => intval($params['group_id']), //接收者ID
'source' => 2, //接收者类型 1:好友;2:群组 'source' => 2, //接收者类型 1:好友;2:群组
@ -246,7 +247,7 @@ class GroupController extends CController
// ...消息推送队列 // ...消息推送队列
$this->producer->produce( $this->producer->produce(
new ChatMessageProducer('event_talk', [ new ChatMessageProducer(SocketConstants::EVENT_TALK, [
'sender' => $user_id, //发送者ID 'sender' => $user_id, //发送者ID
'receive' => intval($params['group_id']), //接收者ID 'receive' => intval($params['group_id']), //接收者ID
'source' => 2, //接收者类型 1:好友;2:群组 'source' => 2, //接收者类型 1:好友;2:群组

View File

@ -21,6 +21,7 @@ use App\Service\UploadService;
use App\Amqp\Producer\ChatMessageProducer; use App\Amqp\Producer\ChatMessageProducer;
use App\Cache\LastMsgCache; use App\Cache\LastMsgCache;
use App\Cache\UnreadTalkCache; use App\Cache\UnreadTalkCache;
use App\Constants\SocketConstants;
/** /**
* Class TalkController * Class TalkController
@ -229,7 +230,7 @@ class TalkController extends CController
[$isTrue, $message,] = $this->talkService->revokeRecord($this->uid(), $params['record_id']); [$isTrue, $message,] = $this->talkService->revokeRecord($this->uid(), $params['record_id']);
if ($isTrue) { if ($isTrue) {
$this->producer->produce( $this->producer->produce(
new ChatMessageProducer('event_revoke_talk', [ new ChatMessageProducer(SocketConstants::EVENT_REVOKE_TALK, [
'record_id' => $params['record_id'] 'record_id' => $params['record_id']
]) ])
); );
@ -326,7 +327,7 @@ class TalkController extends CController
// ...消息推送队列 // ...消息推送队列
foreach ($ids as $value) { foreach ($ids as $value) {
$this->producer->produce( $this->producer->produce(
new ChatMessageProducer('event_talk', [ new ChatMessageProducer(SocketConstants::EVENT_TALK, [
'sender' => $user_id, //发送者ID 'sender' => $user_id, //发送者ID
'receive' => intval($value['receive_id']), //接收者ID 'receive' => intval($value['receive_id']), //接收者ID
'source' => intval($value['source']), //接收者类型 1:好友;2:群组 'source' => intval($value['source']), //接收者类型 1:好友;2:群组
@ -526,7 +527,7 @@ class TalkController extends CController
// ...消息推送队列 // ...消息推送队列
$this->producer->produce( $this->producer->produce(
new ChatMessageProducer('event_talk', [ new ChatMessageProducer(SocketConstants::EVENT_TALK, [
'sender' => $user_id, //发送者ID 'sender' => $user_id, //发送者ID
'receive' => intval($params['receive_id']), //接收者ID 'receive' => intval($params['receive_id']), //接收者ID
'source' => intval($params['source']), //接收者类型 1:好友;2:群组 'source' => intval($params['source']), //接收者类型 1:好友;2:群组
@ -571,7 +572,7 @@ class TalkController extends CController
// ...消息推送队列 // ...消息推送队列
$this->producer->produce( $this->producer->produce(
new ChatMessageProducer('event_talk', [ new ChatMessageProducer(SocketConstants::EVENT_TALK, [
'sender' => $user_id, //发送者ID 'sender' => $user_id, //发送者ID
'receive' => intval($params['receive_id']), //接收者ID 'receive' => intval($params['receive_id']), //接收者ID
'source' => intval($params['source']), //接收者类型 1:好友;2:群组 'source' => intval($params['source']), //接收者类型 1:好友;2:群组
@ -586,6 +587,9 @@ class TalkController extends CController
* 发送文件消息 * 发送文件消息
* *
* @RequestMapping(path="send-file", methods="post") * @RequestMapping(path="send-file", methods="post")
*
* @param UploadService $uploadService
* @return ResponseInterface
*/ */
public function sendFile(UploadService $uploadService) public function sendFile(UploadService $uploadService)
{ {
@ -633,7 +637,7 @@ class TalkController extends CController
// ...消息推送队列 // ...消息推送队列
$this->producer->produce( $this->producer->produce(
new ChatMessageProducer('event_talk', [ new ChatMessageProducer(SocketConstants::EVENT_TALK, [
'sender' => $user_id, //发送者ID 'sender' => $user_id, //发送者ID
'receive' => intval($params['receive_id']), //接收者ID 'receive' => intval($params['receive_id']), //接收者ID
'source' => intval($params['source']), //接收者类型 1:好友;2:群组 'source' => intval($params['source']), //接收者类型 1:好友;2:群组
@ -688,7 +692,7 @@ class TalkController extends CController
// ...消息推送队列 // ...消息推送队列
$this->producer->produce( $this->producer->produce(
new ChatMessageProducer('event_talk', [ new ChatMessageProducer(SocketConstants::EVENT_TALK, [
'sender' => $user_id, //发送者ID 'sender' => $user_id, //发送者ID
'receive' => intval($params['receive_id']), //接收者ID 'receive' => intval($params['receive_id']), //接收者ID
'source' => intval($params['source']), //接收者类型 1:好友;2:群组 'source' => intval($params['source']), //接收者类型 1:好友;2:群组

View File

@ -2,6 +2,7 @@
namespace App\Controller\Api\V1; namespace App\Controller\Api\V1;
use App\Constants\SocketConstants;
use Hyperf\Di\Annotation\Inject; use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller; use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping; use Hyperf\HttpServer\Annotation\RequestMapping;
@ -268,7 +269,7 @@ class UsersController extends CController
//判断对方是否在线。如果在线发送消息通知 //判断对方是否在线。如果在线发送消息通知
if ($this->socketClientService->isOnlineAll((int)$params['friend_id'])) { if ($this->socketClientService->isOnlineAll((int)$params['friend_id'])) {
$this->producer->produce( $this->producer->produce(
new ChatMessageProducer('event_friend_apply', [ new ChatMessageProducer(SocketConstants::EVENT_FRIEND_APPLY, [
'sender' => $user_id, 'sender' => $user_id,
'receive' => (int)$params['friend_id'], 'receive' => (int)$params['friend_id'],
'type' => 1, 'type' => 1,
@ -304,7 +305,7 @@ class UsersController extends CController
if ($this->socketClientService->isOnlineAll((int)$params['friend_id'])) { if ($this->socketClientService->isOnlineAll((int)$params['friend_id'])) {
// 待修改 // 待修改
$this->producer->produce( $this->producer->produce(
new ChatMessageProducer('event_friend_apply', [ new ChatMessageProducer(SocketConstants::EVENT_FRIEND_APPLY, [
'sender' => $user_id, 'sender' => $user_id,
'receive' => (int)$params['friend_id'], 'receive' => (int)$params['friend_id'],
'type' => 1, 'type' => 1,

View File

@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
namespace App\Helper;
/**
* 字符串助手类
*
* Class StringHelper
* @package App\Helper
*/
class StringHelper
{
/**
* 将字符串转换成二进制
*
* @param string $str
* @return string
*/
public static function str2Bin(string $str): string
{
//列出每个字符
$arr = preg_split('/(?<!^)(?!$)/u', $str);
//unpack字符
foreach ($arr as &$v) {
$temp = unpack('H*', $v);
$v = base_convert($temp[1], 16, 2);
unset($temp);
}
return join(' ', $arr);
}
/**
* 将二进制转换成字符串
*
* @param string $str
* @return string
*/
public static function bin2Str(string $str): string
{
$arr = explode(' ', $str);
foreach ($arr as &$v) {
$v = pack('H' . strlen(base_convert($v, 2, 16)), base_convert($v, 2, 16));
}
return join('', $arr);
}
}

View File

@ -37,5 +37,10 @@ class ChatRecordsDelete extends BaseModel
* *
* @var array * @var array
*/ */
protected $casts = ['id' => 'integer', 'record_id' => 'integer', 'user_id' => 'integer', 'created_at' => 'datetime']; protected $casts = [
'id' => 'integer',
'record_id' => 'integer',
'user_id' => 'integer',
'created_at' => 'datetime'
];
} }

View File

@ -50,7 +50,6 @@ class FileSplitUpload extends BaseModel
'upload_at' 'upload_at'
]; ];
/** /**
* The attributes that should be cast to native types. * The attributes that should be cast to native types.
* *

View File

@ -69,7 +69,8 @@ class UsersGroup extends BaseModel
* @param int $group_id 群ID * @param int $group_id 群ID
* @return mixed * @return mixed
*/ */
public static function isManager(int $user_id,int $group_id){ public static function isManager(int $user_id, int $group_id)
{
return self::where('id', $group_id)->where('user_id', $user_id)->exists(); return self::where('id', $group_id)->where('user_id', $user_id)->exists();
} }
@ -82,6 +83,6 @@ class UsersGroup extends BaseModel
*/ */
public static function isMember(int $group_id, int $user_id) public static function isMember(int $group_id, int $user_id)
{ {
return UsersGroupMember::where('group_id', $group_id)->where('user_id', $user_id)->where('status', 0)->exists() ? true : false; return UsersGroupMember::where('group_id', $group_id)->where('user_id', $user_id)->where('status', 0)->exists();
} }
} }

View File

@ -118,7 +118,10 @@ class UsersChatList extends BaseModel
*/ */
public static function topItem(int $user_id, int $list_id, $is_top = true) public static function topItem(int $user_id, int $list_id, $is_top = true)
{ {
return (bool)self::where('id', $list_id)->where('uid', $user_id)->update(['is_top' => $is_top ? 1 : 0, 'updated_at' => date('Y-m-d H:i:s')]); return (bool)self::where('id', $list_id)->where('uid', $user_id)->update([
'is_top' => $is_top ? 1 : 0,
'updated_at' => date('Y-m-d H:i:s')
]);
} }
/** /**
@ -131,12 +134,13 @@ class UsersChatList extends BaseModel
*/ */
public static function delItem(int $user_id, int $id, $type = 1) public static function delItem(int $user_id, int $id, $type = 1)
{ {
$data = ['status' => 0, 'updated_at' => date('Y-m-d H:i:s')];
if ($type == 1) { if ($type == 1) {
return (bool)self::where('id', $id)->where('uid', $user_id)->update(['status' => 0, 'updated_at' => date('Y-m-d H:i:s')]); return (bool)self::where('id', $id)->where('uid', $user_id)->update($data);
} else if ($type == 2) { } else if ($type == 2) {
return (bool)self::where('uid', $user_id)->where('friend_id', $id)->update(['status' => 0, 'updated_at' => date('Y-m-d H:i:s')]); return (bool)self::where('uid', $user_id)->where('friend_id', $id)->update($data);
} else { } else {
return (bool)self::where('uid', $user_id)->where('group_id', $id)->update(['status' => 0, 'updated_at' => date('Y-m-d H:i:s')]); return (bool)self::where('uid', $user_id)->where('group_id', $id)->update($data);
} }
} }

View File

@ -76,7 +76,7 @@ class UsersFriend extends BaseModel
SELECT id as rid,user2 as uid,user1_remark as friend_remark from {$prefix}users_friends where user1 = {$uid} and `status` = 1 SELECT id as rid,user2 as uid,user1_remark as friend_remark from {$prefix}users_friends where user1 = {$uid} and `status` = 1
UNION all UNION all
SELECT id as rid,user1 as uid,user2_remark as friend_remark from {$prefix}users_friends where user2 = {$uid} and `status` = 1 SELECT id as rid,user1 as uid,user2_remark as friend_remark from {$prefix}users_friends where user2 = {$uid} and `status` = 1
) tmp_table on tmp_table.uid = users.id order by tmp_table.rid desc ) tmp_table on tmp_table.uid = users.id
SQL; SQL;
$rows = Db::select($sql); $rows = Db::select($sql);

View File

@ -240,7 +240,7 @@ class TalkService extends BaseService
* @param int $record_id 上一次查询的聊天记录ID * @param int $record_id 上一次查询的聊天记录ID
* @param int $limit 查询数据长度 * @param int $limit 查询数据长度
* @param array $msg_type 消息类型 * @param array $msg_type 消息类型
* @return mixed * @return array
*/ */
public function getChatRecords(int $user_id, int $receive_id, int $source, int $record_id, $limit = 30, $msg_type = []) public function getChatRecords(int $user_id, int $receive_id, int $source, int $record_id, $limit = 30, $msg_type = [])
{ {
@ -417,7 +417,6 @@ class TalkService extends BaseService
* @param int $record_id 转发消息的记录ID * @param int $record_id 转发消息的记录ID
* @param array $receive_ids 接受者数组 例如:[['source' => 1,'id' => 3045],['source' => 1,'id' => 3046],['source' => 1,'id' => 1658]] 二维数组 * @param array $receive_ids 接受者数组 例如:[['source' => 1,'id' => 3045],['source' => 1,'id' => 3046],['source' => 1,'id' => 1658]] 二维数组
* @return array * @return array
* @throws \Exception
*/ */
public function forwardRecords(int $user_id, int $record_id, array $receive_ids) public function forwardRecords(int $user_id, int $record_id, array $receive_ids)
{ {
@ -477,7 +476,7 @@ class TalkService extends BaseService
'save_dir' => $fileInfo->save_dir, 'save_dir' => $fileInfo->save_dir,
'created_at' => date('Y-m-d H:i:s') 'created_at' => date('Y-m-d H:i:s')
])) { ])) {
throw new \Exception('插入文件消息记录失败'); throw new Exception('插入文件消息记录失败');
} }
} else if ($result->msg_type == 5) { } else if ($result->msg_type == 5) {
if (!ChatRecordsCode::create([ if (!ChatRecordsCode::create([
@ -487,7 +486,7 @@ class TalkService extends BaseService
'code' => $codeBlock->code, 'code' => $codeBlock->code,
'created_at' => date('Y-m-d H:i:s') 'created_at' => date('Y-m-d H:i:s')
])) { ])) {
throw new \Exception('插入代码消息记录失败'); throw new Exception('插入代码消息记录失败');
} }
} }
} }
@ -696,17 +695,17 @@ class TalkService extends BaseService
$insert = ChatRecord::create($message); $insert = ChatRecord::create($message);
if (!$insert) { if (!$insert) {
throw new \Exception('插入聊天记录失败...'); throw new Exception('插入聊天记录失败...');
} }
$fileInfo['record_id'] = $insert->id; $fileInfo['record_id'] = $insert->id;
$fileInfo['created_at'] = date('Y-m-d H:i:s'); $fileInfo['created_at'] = date('Y-m-d H:i:s');
if (!ChatRecordsFile::create($fileInfo)) { if (!ChatRecordsFile::create($fileInfo)) {
throw new \Exception('插入聊天记录(文件消息)失败...'); throw new Exception('插入聊天记录(文件消息)失败...');
} }
Db::commit(); Db::commit();
} catch (\Exception $e) { } catch (Exception $e) {
Db::rollBack(); Db::rollBack();
return false; return false;
} }
@ -728,17 +727,17 @@ class TalkService extends BaseService
$message['created_at'] = date('Y-m-d H:i:s'); $message['created_at'] = date('Y-m-d H:i:s');
$insert = ChatRecord::create($message); $insert = ChatRecord::create($message);
if (!$insert) { if (!$insert) {
throw new \Exception('插入聊天记录失败...'); throw new Exception('插入聊天记录失败...');
} }
$codeBlock['record_id'] = $insert->id; $codeBlock['record_id'] = $insert->id;
$codeBlock['created_at'] = date('Y-m-d H:i:s'); $codeBlock['created_at'] = date('Y-m-d H:i:s');
if (!ChatRecordsCode::create($codeBlock)) { if (!ChatRecordsCode::create($codeBlock)) {
throw new \Exception('插入聊天记录(代码消息)失败...'); throw new Exception('插入聊天记录(代码消息)失败...');
} }
Db::commit(); Db::commit();
} catch (\Exception $e) { } catch (Exception $e) {
Db::rollBack(); Db::rollBack();
return false; return false;
} }
@ -760,17 +759,17 @@ class TalkService extends BaseService
$message['created_at'] = date('Y-m-d H:i:s'); $message['created_at'] = date('Y-m-d H:i:s');
$insert = ChatRecord::create($message); $insert = ChatRecord::create($message);
if (!$insert) { if (!$insert) {
throw new \Exception('插入聊天记录失败...'); throw new Exception('插入聊天记录失败...');
} }
$emoticon['record_id'] = $insert->id; $emoticon['record_id'] = $insert->id;
$emoticon['created_at'] = date('Y-m-d H:i:s'); $emoticon['created_at'] = date('Y-m-d H:i:s');
if (!ChatRecordsFile::create($emoticon)) { if (!ChatRecordsFile::create($emoticon)) {
throw new \Exception('插入聊天记录(代码消息)失败...'); throw new Exception('插入聊天记录(代码消息)失败...');
} }
Db::commit(); Db::commit();
} catch (\Exception $e) { } catch (Exception $e) {
Db::rollBack(); Db::rollBack();
return false; return false;
} }
@ -792,17 +791,17 @@ class TalkService extends BaseService
$message['created_at'] = date('Y-m-d H:i:s'); $message['created_at'] = date('Y-m-d H:i:s');
$insert = ChatRecord::create($message); $insert = ChatRecord::create($message);
if (!$insert) { if (!$insert) {
throw new \Exception('插入聊天记录失败...'); throw new Exception('插入聊天记录失败...');
} }
$emoticon['record_id'] = $insert->id; $emoticon['record_id'] = $insert->id;
$emoticon['created_at'] = date('Y-m-d H:i:s'); $emoticon['created_at'] = date('Y-m-d H:i:s');
if (!ChatRecordsFile::create($emoticon)) { if (!ChatRecordsFile::create($emoticon)) {
throw new \Exception('插入聊天记录(代码消息)失败...'); throw new Exception('插入聊天记录(代码消息)失败...');
} }
Db::commit(); Db::commit();
} catch (\Exception $e) { } catch (Exception $e) {
Db::rollBack(); Db::rollBack();
return false; return false;
} }

View File

@ -38,7 +38,7 @@ function redis()
} }
/** /**
* server 实例 基于 swoole server * Server 实例 基于 Swoole Server
* *
* @return \Swoole\Coroutine\Server|\Swoole\Server * @return \Swoole\Coroutine\Server|\Swoole\Server
*/ */
@ -48,7 +48,9 @@ function server()
} }
/** /**
* websocket frame 实例 * WebSocket frame 实例
*
* @return mixed|Frame
*/ */
function frame() function frame()
{ {
@ -56,7 +58,9 @@ function frame()
} }
/** /**
* websocket 实例 * WebSocketServer 实例
*
* @return mixed|WebSocketServer
*/ */
function websocket() function websocket()
{ {
@ -65,6 +69,8 @@ function websocket()
/** /**
* 缓存实例 简单的缓存 * 缓存实例 简单的缓存
*
* @return mixed|\Psr\SimpleCache\CacheInterface
*/ */
function cache() function cache()
{ {
@ -73,6 +79,8 @@ function cache()
/** /**
* 控制台日志 * 控制台日志
*
* @return StdoutLoggerInterface|mixed
*/ */
function stdout_log() function stdout_log()
{ {
@ -112,7 +120,9 @@ function response()
/** /**
* 从HTML文本中提取所有图片 * 从HTML文本中提取所有图片
* @param $content *
* @param string $content HTML文本
*
* @return array * @return array
*/ */
function get_html_images($content) function get_html_images($content)
@ -133,8 +143,9 @@ function get_html_images($content)
/** /**
* 获取两个日期相差多少天 * 获取两个日期相差多少天
* *
* @param $day1 * @param string $day1 日期1
* @param $day2 * @param string $day2 日期2
*
* @return float|int * @return float|int
*/ */
function diff_date($day1, $day2) function diff_date($day1, $day2)
@ -153,6 +164,7 @@ function diff_date($day1, $day2)
* 获取媒体文件url * 获取媒体文件url
* *
* @param string $path 文件相对路径 * @param string $path 文件相对路径
*
* @return string * @return string
*/ */
function get_media_url(string $path) function get_media_url(string $path)
@ -166,6 +178,7 @@ function get_media_url(string $path)
* @param string $ext 图片后缀名 * @param string $ext 图片后缀名
* @param int $width 图片宽度 * @param int $width 图片宽度
* @param int $height 图片高度 * @param int $height 图片高度
*
* @return string * @return string
*/ */
function create_image_name(string $ext, int $width, int $height) function create_image_name(string $ext, int $width, int $height)
@ -176,7 +189,8 @@ function create_image_name(string $ext, int $width, int $height)
/** /**
* 替换文本中的url a标签 * 替换文本中的url a标签
* *
* @param string $str * @param string $str 字符串
*
* @return null|string|string[] * @return null|string|string[]
*/ */
function replace_url_link(string $str) function replace_url_link(string $str)

View File

@ -4,6 +4,7 @@ use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint; use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration; use Hyperf\Database\Migrations\Migration;
use Hyperf\DbConnection\Db; use Hyperf\DbConnection\Db;
class CreateUsersFriendsTable extends Migration class CreateUsersFriendsTable extends Migration
{ {
/** /**
@ -27,6 +28,7 @@ class CreateUsersFriendsTable extends Migration
$table->engine = 'InnoDB'; $table->engine = 'InnoDB';
$table->index(['user1', 'user2'], 'idx_user1_user2'); $table->index(['user1', 'user2'], 'idx_user1_user2');
$table->index(['user2', 'user1'], 'idx_user2_user1');
}); });
$prefix = config('databases.default.prefix'); $prefix = config('databases.default.prefix');