初始化基础模型
This commit is contained in:
parent
e38f2ee2b6
commit
8e770b02fe
19687
_ide_helper.php
Normal file
19687
_ide_helper.php
Normal file
File diff suppressed because it is too large
Load Diff
27
app/Events/ServerStartEvent.php
Normal file
27
app/Events/ServerStartEvent.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use Hhxsv5\LaravelS\Swoole\Events\ServerStartInterface;
|
||||
use Swoole\Http\Server;
|
||||
|
||||
class ServerStartEvent implements ServerStartInterface
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function handle(Server $server)
|
||||
{
|
||||
$server->startMsecTime = $this->msecTime();
|
||||
}
|
||||
|
||||
private function msecTime()
|
||||
{
|
||||
list($msec, $sec) = explode(' ', microtime());
|
||||
$time = explode(".", $sec . ($msec * 1000));
|
||||
return $time[0];
|
||||
}
|
||||
}
|
24
app/Events/WorkerStartEvent.php
Normal file
24
app/Events/WorkerStartEvent.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use App\Models\WebSocket;
|
||||
use Cache;
|
||||
use Hhxsv5\LaravelS\Swoole\Events\WorkerStartInterface;
|
||||
use Swoole\Http\Server;
|
||||
|
||||
class WorkerStartEvent implements WorkerStartInterface
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function handle(Server $server, $workerId)
|
||||
{
|
||||
if (isset($server->startMsecTime) && Cache::get("swooleServerStartMsecTime") != $server->startMsecTime) {
|
||||
Cache::forever("swooleServerStartMsecTime", $server->startMsecTime);
|
||||
WebSocket::query()->delete();
|
||||
}
|
||||
}
|
||||
}
|
33
app/Http/Controllers/IndexController.php
Executable file
33
app/Http/Controllers/IndexController.php
Executable file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Module\Base;
|
||||
use Redirect;
|
||||
|
||||
|
||||
/**
|
||||
* 页面
|
||||
* Class IndexController
|
||||
* @package App\Http\Controllers
|
||||
*/
|
||||
class IndexController extends InvokeController
|
||||
{
|
||||
/**
|
||||
* 首页
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
*/
|
||||
public function main()
|
||||
{
|
||||
return view('main', ['version' => Base::getVersion()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口文档
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function api()
|
||||
{
|
||||
return Redirect::to(Base::fillUrl('docs/index.html'), 301);
|
||||
}
|
||||
}
|
70
app/Http/Controllers/InvokeController.php
Normal file
70
app/Http/Controllers/InvokeController.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Module\Base;
|
||||
use App\Tasks\IhttpTask;
|
||||
use Hhxsv5\LaravelS\Swoole\Task\Task;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use Request;
|
||||
|
||||
class InvokeController extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||
|
||||
/**
|
||||
* @param $method
|
||||
* @param string $action
|
||||
* @return array|void
|
||||
*/
|
||||
public function __invoke($method, $action = '')
|
||||
{
|
||||
$app = $method ?: 'main';
|
||||
if ($action) {
|
||||
$app .= "__" . $action;
|
||||
}
|
||||
// 接口不存在
|
||||
if (!method_exists($this, $app)) {
|
||||
$msg = "404 not found (" . str_replace("__", "/", $app) . ").";
|
||||
return Base::ajaxError($msg);
|
||||
}
|
||||
// 使用websocket请求
|
||||
$apiWebsocket = Request::header('Api-Websocket');
|
||||
if ($apiWebsocket) {
|
||||
$userid = User::token2userid();
|
||||
if ($userid > 0) {
|
||||
$url = 'http://127.0.0.1:' . env('LARAVELS_LISTEN_PORT') . Request::getRequestUri();
|
||||
$task = new IhttpTask($url, Request::post(), [
|
||||
'Content-Type' => Request::header('Content-Type'),
|
||||
'language' => Request::header('language'),
|
||||
'token' => Request::header('token'),
|
||||
]);
|
||||
$task->setApiWebsocket($apiWebsocket);
|
||||
$task->setApiUserid($userid);
|
||||
Task::deliver($task);
|
||||
return Base::retSuccess('wait');
|
||||
}
|
||||
}
|
||||
// 正常请求
|
||||
$res = $this->__before($method, $action);
|
||||
if ($res === true || Base::isSuccess($res)) {
|
||||
return $this->$app();
|
||||
} else {
|
||||
return is_array($res) ? $res : Base::ajaxError($res);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $method
|
||||
* @param $action
|
||||
* @return bool|array|string
|
||||
*/
|
||||
public function __before($method, $action)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
@ -62,5 +62,7 @@ class Kernel extends HttpKernel
|
||||
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
|
||||
'webapi' => \App\Http\Middleware\WebApi::class,
|
||||
];
|
||||
}
|
||||
|
25
app/Http/Middleware/WebApi.php
Normal file
25
app/Http/Middleware/WebApi.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
@error_reporting(E_ALL & ~E_NOTICE);
|
||||
|
||||
use Closure;
|
||||
|
||||
class WebApi
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
global $_A;
|
||||
$_A = [];
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
180
app/Models/AbstractModel.php
Normal file
180
app/Models/AbstractModel.php
Normal file
@ -0,0 +1,180 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Module\Base;
|
||||
use DateTimeInterface;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
/**
|
||||
* App\Model\AbstractModel
|
||||
*
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel getKeyValue()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|static with($relations)
|
||||
* @method static \Illuminate\Database\Query\Builder|static select($columns = [])
|
||||
* @method static \Illuminate\Database\Query\Builder|static whereNotIn($column, $values, $boolean = 'and')
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class AbstractModel extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
const ID = 'id';
|
||||
|
||||
protected $dates = [
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'deleted_at',
|
||||
];
|
||||
|
||||
/**
|
||||
* 获取模型主键的值(如果没有则先保存)
|
||||
* @return mixed
|
||||
*/
|
||||
protected function scopeGetKeyValue()
|
||||
{
|
||||
$key = $this->getKeyName();
|
||||
if (!isset($this->$key)) {
|
||||
$this->save();
|
||||
}
|
||||
return $this->$key;
|
||||
}
|
||||
|
||||
/**
|
||||
* 为数组 / JSON 序列化准备日期。
|
||||
* @param DateTimeInterface $date
|
||||
* @return string
|
||||
*/
|
||||
protected function serializeDate(DateTimeInterface $date)
|
||||
{
|
||||
return $date->format($this->dateFormat ?: 'Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建/更新数据
|
||||
* @param array $param
|
||||
* @param null $id
|
||||
* @return AbstractModel|AbstractModel[]|\Illuminate\Database\Eloquent\Collection|Model|static
|
||||
*/
|
||||
public static function createInstance($param = [], $id = null)
|
||||
{
|
||||
if ($id) {
|
||||
$instance = static::findOrFail($id);
|
||||
} else {
|
||||
$instance = new static;
|
||||
}
|
||||
if ($param) {
|
||||
$instance->updateInstance($param);
|
||||
}
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新数据校验
|
||||
* @param array $param
|
||||
*/
|
||||
public function updateInstance(array $param)
|
||||
{
|
||||
foreach ($param AS $k => $v) {
|
||||
if (is_array($v)) {
|
||||
$v = Base::array2json($v);
|
||||
}
|
||||
$this->$k = $v;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据条件更新数据
|
||||
* @param $where
|
||||
* @param $updateArray
|
||||
* @return bool
|
||||
*/
|
||||
public static function updateData($where, $updateArray)
|
||||
{
|
||||
$isUpdate = false;
|
||||
if ($updateArray) {
|
||||
$result = self::transaction(function () use ($updateArray, $where) {
|
||||
$list = static::where($where)->get();
|
||||
if ($list->isNotEmpty()) {
|
||||
foreach ($list AS $row) {
|
||||
$row->updateInstance($updateArray);
|
||||
$row->save();
|
||||
}
|
||||
}
|
||||
});
|
||||
$isUpdate = Base::isSuccess($result);
|
||||
}
|
||||
return $isUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据库更新或插入
|
||||
* @param $where
|
||||
* @param array $update 存在时更新的内容
|
||||
* @param array $insert 不存在时插入的内容,如果没有则插入更新内容
|
||||
* @return bool
|
||||
*/
|
||||
public static function updateInsert($where, $update = [], $insert = [])
|
||||
{
|
||||
$row = static::where($where)->first();
|
||||
if (empty($row)) {
|
||||
$row = new static;
|
||||
$row->updateInstance(array_merge($where, $insert ?: $update));
|
||||
} elseif ($update) {
|
||||
$row->updateInstance($update);
|
||||
}
|
||||
return $row->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* 定义变量为对象(IDE高亮)
|
||||
* @param $value
|
||||
* @return static
|
||||
*/
|
||||
public static function IDE($value)
|
||||
{
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用于Model的事务处理
|
||||
* @param \Closure $closure
|
||||
* @return array
|
||||
*/
|
||||
public static function transaction(\Closure $closure)
|
||||
{
|
||||
//开启事务
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
$result = $closure();
|
||||
if (is_bool($result)) {
|
||||
if ($result === false) {
|
||||
throw new \Exception('处理失败!'); // 错误:① 返回faske
|
||||
}
|
||||
} elseif ($result) {
|
||||
if (is_string($result)) {
|
||||
throw new \Exception($result); // 错误:② 返回字符串(错误描述)
|
||||
} elseif (is_array($result)
|
||||
&& Base::isError($result)) {
|
||||
throw new \Exception($result['msg']); // 错误:③ 返回数组,且ret=0
|
||||
}
|
||||
}
|
||||
DB::commit();
|
||||
return $result ?: Base::retSuccess('success');
|
||||
} catch (\Throwable $e) {
|
||||
info($e);
|
||||
//接收异常处理并回滚
|
||||
try {
|
||||
DB::rollBack();
|
||||
} catch (\Throwable $eb) {
|
||||
info($eb);
|
||||
}
|
||||
return Base::retError($e->getMessage() ?: '处理错误!');
|
||||
}
|
||||
}
|
||||
}
|
12
app/Models/Setting.php
Normal file
12
app/Models/Setting.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
/**
|
||||
* Class Setting
|
||||
* @package App\Models
|
||||
*/
|
||||
class Setting extends AbstractModel
|
||||
{
|
||||
|
||||
}
|
12
app/Models/Tmp.php
Normal file
12
app/Models/Tmp.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
/**
|
||||
* Class Tmp
|
||||
* @package App\Models
|
||||
*/
|
||||
class Tmp extends AbstractModel
|
||||
{
|
||||
|
||||
}
|
@ -2,42 +2,344 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
|
||||
class User extends Authenticatable
|
||||
use App\Module\Base;
|
||||
use Cache;
|
||||
|
||||
/**
|
||||
* Class User
|
||||
* @package App\Models
|
||||
*/
|
||||
class User extends AbstractModel
|
||||
{
|
||||
use HasFactory, Notifiable;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'email',
|
||||
'password',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for arrays.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
'encrypt',
|
||||
'userpass',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
*
|
||||
* @var array
|
||||
* 昵称
|
||||
* @param $value
|
||||
* @return string
|
||||
*/
|
||||
protected $casts = [
|
||||
'email_verified_at' => 'datetime',
|
||||
];
|
||||
public function getNicknameAttribute($value)
|
||||
{
|
||||
return $value ?: $this->username;
|
||||
}
|
||||
|
||||
/**
|
||||
* 头像地址
|
||||
* @param $value
|
||||
* @return string
|
||||
*/
|
||||
public function getUseringAttribute($value)
|
||||
{
|
||||
return self::userimg($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 身份权限
|
||||
* @param $value
|
||||
* @return array
|
||||
*/
|
||||
public function getIdentityAttribute($value)
|
||||
{
|
||||
return is_array($value) ? $value : explode(",", trim($value, ","));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* userid获取用户名
|
||||
* @param $userid
|
||||
* @return mixed
|
||||
*/
|
||||
public static function userid2username($userid)
|
||||
{
|
||||
if (empty($userid)) {
|
||||
return '';
|
||||
}
|
||||
return self::whereUserid(intval($userid))->value('username');
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户名获取userid
|
||||
* @param $username
|
||||
* @return int
|
||||
*/
|
||||
public static function username2userid($username)
|
||||
{
|
||||
if (empty($username)) {
|
||||
return 0;
|
||||
}
|
||||
return intval(self::whereUsername($username)->value('userid'));
|
||||
}
|
||||
|
||||
/**
|
||||
* token获取会员userid
|
||||
* @return int
|
||||
*/
|
||||
public static function token2userid()
|
||||
{
|
||||
return self::authFind('userid', Base::getToken());
|
||||
}
|
||||
|
||||
/**
|
||||
* token获取会员账号
|
||||
* @return int
|
||||
*/
|
||||
public static function token2username()
|
||||
{
|
||||
return self::authFind('username', Base::getToken());
|
||||
}
|
||||
|
||||
/**
|
||||
* token获取encrypt
|
||||
* @return mixed|string
|
||||
*/
|
||||
public static function token2encrypt()
|
||||
{
|
||||
return self::authFind('encrypt', Base::getToken());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取token身份信息
|
||||
* @param $find
|
||||
* @param null $token
|
||||
* @return array|mixed|string
|
||||
*/
|
||||
public static function authFind($find, $token = null)
|
||||
{
|
||||
if ($token === null) {
|
||||
$token = Base::getToken();
|
||||
}
|
||||
list($userid, $username, $encrypt, $timestamp) = explode("@", base64_decode($token) . "@@@@");
|
||||
$array = [
|
||||
'userid' => intval($userid),
|
||||
'username' => $username ?: '',
|
||||
'encrypt' => $encrypt ?: '',
|
||||
'timestamp' => intval($timestamp),
|
||||
];
|
||||
if (isset($array[$find])) {
|
||||
return $array[$find];
|
||||
}
|
||||
if ($find == 'all') {
|
||||
return $array;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户身份认证(获取用户信息)
|
||||
* @return array|mixed
|
||||
*/
|
||||
public static function auth()
|
||||
{
|
||||
global $_A;
|
||||
if (isset($_A["__static_auth"])) {
|
||||
return $_A["__static_auth"];
|
||||
}
|
||||
$authorization = Base::getToken();
|
||||
if ($authorization) {
|
||||
$authInfo = self::authFind('all', $authorization);
|
||||
if ($authInfo['userid'] > 0) {
|
||||
$loginValid = floatval(Base::settingFind('system', 'loginValid')) ?: 720;
|
||||
$loginValid *= 3600;
|
||||
if ($authInfo['timestamp'] + $loginValid > time()) {
|
||||
$row = self::whereUserid($authInfo['userid'])->whereUsername($authInfo['username'])->whereEncrypt($authInfo['encrypt'])->first();
|
||||
if ($row) {
|
||||
if ($row->token) {
|
||||
$timestamp = self::authFind('timestamp', $row->token);
|
||||
if ($timestamp + $loginValid > time()) {
|
||||
$upArray = [];
|
||||
if (Base::getIp() && $row->lineip != Base::getIp()) {
|
||||
$upArray['lineip'] = Base::getIp();
|
||||
}
|
||||
if ($row->linedate + 30 < time()) {
|
||||
$upArray['linedate'] = time();
|
||||
}
|
||||
if ($upArray) {
|
||||
$row->updateInstance($upArray);
|
||||
$row->save();
|
||||
}
|
||||
return $_A["__static_auth"] = $row;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $_A["__static_auth"] = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户身份认证(获取用户信息)
|
||||
* @return array
|
||||
*/
|
||||
public static function authE()
|
||||
{
|
||||
$user = self::auth();
|
||||
if (!$user) {
|
||||
$authorization = Base::getToken();
|
||||
if ($authorization) {
|
||||
return Base::retError('身份已失效,请重新登录!', $user, -1);
|
||||
} else {
|
||||
return Base::retError('请登录后继续...', [], -1);
|
||||
}
|
||||
}
|
||||
return Base::retSuccess("auth", $user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成token
|
||||
* @param $userinfo
|
||||
* @return string
|
||||
*/
|
||||
public static function token($userinfo)
|
||||
{
|
||||
return base64_encode($userinfo['userid'] . '@' . $userinfo['username'] . '@' . $userinfo['encrypt'] . '@' . time() . '@' . Base::generatePassword(6));
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断用户权限(身份)
|
||||
* @param $identity
|
||||
* @return array
|
||||
*/
|
||||
public static function identity($identity)
|
||||
{
|
||||
$user = self::auth();
|
||||
if (is_array($user->identity)
|
||||
&& in_array($identity, $user->identity)) {
|
||||
return Base::retSuccess("success");
|
||||
}
|
||||
return Base::retError("权限不足!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断用户权限(身份)
|
||||
* @param $identity
|
||||
* @return bool
|
||||
*/
|
||||
public static function identityCheck($identity)
|
||||
{
|
||||
if (is_array($identity)) {
|
||||
foreach ($identity as $id) {
|
||||
if (!Base::isError(self::identity($id)))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return Base::isSuccess(self::identity($identity));
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断用户权限(身份)
|
||||
* @param $identity
|
||||
* @param $userIdentity
|
||||
* @return bool
|
||||
*/
|
||||
public static function identityRaw($identity, $userIdentity)
|
||||
{
|
||||
$userIdentity = is_array($userIdentity) ? $userIdentity : explode(",", trim($userIdentity, ","));
|
||||
return $identity && in_array($identity, $userIdentity);
|
||||
}
|
||||
|
||||
/**
|
||||
* userid 获取 基本信息
|
||||
* @param int $userid 会员ID
|
||||
* @return array
|
||||
*/
|
||||
public static function userid2basic(int $userid)
|
||||
{
|
||||
global $_A;
|
||||
if (empty($userid)) {
|
||||
return [];
|
||||
}
|
||||
if (isset($_A["__static_userid2basic_" . $userid])) {
|
||||
return $_A["__static_userid2basic_" . $userid];
|
||||
}
|
||||
$fields = ['userid', 'username', 'nickname', 'userimg'];
|
||||
$userInfo = self::whereUserid($userid)->select($fields)->first();
|
||||
if ($userInfo) {
|
||||
$userInfo->userimg = self::userimg($userInfo->userimg);
|
||||
}
|
||||
return $_A["__static_userid2basic_" . $userid] = ($userInfo ?: []);
|
||||
}
|
||||
|
||||
/**
|
||||
* username 获取 基本信息
|
||||
* @param string $username 用户名
|
||||
* @return array
|
||||
*/
|
||||
public static function username2basic(string $username)
|
||||
{
|
||||
global $_A;
|
||||
if (empty($username)) {
|
||||
return [];
|
||||
}
|
||||
if (isset($_A["__static_username2basic_" . $username])) {
|
||||
return $_A["__static_username2basic_" . $username];
|
||||
}
|
||||
$fields = ['userid', 'username', 'nickname', 'userimg'];
|
||||
$userInfo = self::whereUsername($username)->select($fields)->first();
|
||||
if ($userInfo) {
|
||||
$userInfo->userimg = self::userimg($userInfo->userimg);
|
||||
}
|
||||
return $_A["__static_username2basic_" . $username] = ($userInfo ?: []);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户头像,不存在时返回默认
|
||||
* @param string $var 头像地址 或 会员用户名
|
||||
* @return string
|
||||
*/
|
||||
public static function userimg(string $var)
|
||||
{
|
||||
if (!Base::strExists($var, '.')) {
|
||||
if (empty($var)) {
|
||||
$var = "";
|
||||
} else {
|
||||
$userInfo = self::username2basic($var);
|
||||
$var = $userInfo['userimg'];
|
||||
}
|
||||
}
|
||||
return $var ? Base::fillUrl($var) : url('images/other/avatar.png');
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新首字母
|
||||
* @param $userid
|
||||
*/
|
||||
public static function AZUpdate($userid)
|
||||
{
|
||||
$row = self::whereUserid($userid)->select(['username', 'nickname'])->first();
|
||||
if ($row) {
|
||||
$row->az = Base::getFirstCharter($row->nickname);
|
||||
$row->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否需要验证码
|
||||
* @param $username
|
||||
* @return array
|
||||
*/
|
||||
public static function needCode($username)
|
||||
{
|
||||
$loginCode = Base::settingFind('system', 'loginCode');
|
||||
switch ($loginCode) {
|
||||
case 'open':
|
||||
return Base::retSuccess('need');
|
||||
|
||||
case 'close':
|
||||
return Base::retError('no');
|
||||
|
||||
default:
|
||||
if (Cache::get("code::" . $username) == 'need') {
|
||||
return Base::retSuccess('need');
|
||||
} else {
|
||||
return Base::retError('no');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
12
app/Models/WebSocket.php
Normal file
12
app/Models/WebSocket.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
/**
|
||||
* Class WebSocket
|
||||
* @package App\Model
|
||||
*/
|
||||
class WebSocket extends AbstractModel
|
||||
{
|
||||
|
||||
}
|
12
app/Models/WebSocketTmpMsg.php
Normal file
12
app/Models/WebSocketTmpMsg.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
/**
|
||||
* Class WebSocketTmpMsg
|
||||
* @package App\Models
|
||||
*/
|
||||
class WebSocketTmpMsg extends AbstractModel
|
||||
{
|
||||
|
||||
}
|
2795
app/Module/Base.php
Executable file
2795
app/Module/Base.php
Executable file
File diff suppressed because it is too large
Load Diff
288
app/Module/Ihttp.php
Executable file
288
app/Module/Ihttp.php
Executable file
@ -0,0 +1,288 @@
|
||||
<?php
|
||||
|
||||
namespace App\Module;
|
||||
|
||||
use Exception;
|
||||
|
||||
@error_reporting(E_ALL & ~E_NOTICE);
|
||||
|
||||
class Ihttp
|
||||
{
|
||||
|
||||
public static function ihttp_request($url, $post = [], $extra = [], $timeout = 60, $retRaw = false, $isGb2312 = false) {
|
||||
$urlset = parse_url($url);
|
||||
if(empty($urlset['path'])) {
|
||||
$urlset['path'] = '/';
|
||||
}
|
||||
if(!empty($urlset['query'])) {
|
||||
$urlset['query'] = "?{$urlset['query']}";
|
||||
}
|
||||
if(empty($urlset['port'])) {
|
||||
$urlset['port'] = $urlset['scheme'] == 'https' ? '443' : '80';
|
||||
}
|
||||
if (Base::strExists($url, 'https://') && !extension_loaded('openssl')) {
|
||||
if (!extension_loaded("openssl")) {
|
||||
return Base::retError('请开启您PHP环境的openssl');
|
||||
}
|
||||
}
|
||||
Base::addLog([
|
||||
'url' => $url,
|
||||
'post' => $post,
|
||||
], 'before_' . $url);
|
||||
if (function_exists('curl_init') && function_exists('curl_exec')) {
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $urlset['scheme']. '://' .$urlset['host'].($urlset['port'] == '80' ? '' : ':'.$urlset['port']).$urlset['path'].$urlset['query']);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_HEADER, 1);
|
||||
if($post) {
|
||||
if (is_array($post)) {
|
||||
$filepost = false;
|
||||
foreach ($post as $name => $value) {
|
||||
if (is_string($value) && substr($value, 0, 1) == '@') {
|
||||
$filepost = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$filepost) {
|
||||
$post = http_build_query($post);
|
||||
}
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
curl_setopt($ch, CURLOPT_SSLVERSION, 1);
|
||||
if (defined('CURL_SSLVERSION_TLSv1')) {
|
||||
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:9.0.1) Gecko/20100101 Firefox/9.0.1');
|
||||
if (!empty($extra) && is_array($extra)) {
|
||||
$headers = array();
|
||||
foreach ($extra as $opt => $value) {
|
||||
if (Base::strExists($opt, 'CURLOPT_')) {
|
||||
curl_setopt($ch, constant($opt), $value);
|
||||
} elseif (is_numeric($opt)) {
|
||||
curl_setopt($ch, $opt, $value);
|
||||
} else {
|
||||
$headers[] = "{$opt}: {$value}";
|
||||
}
|
||||
}
|
||||
if(!empty($headers)) {
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
}
|
||||
}
|
||||
$data = curl_exec($ch);
|
||||
//$status = curl_getinfo($ch);
|
||||
$errno = curl_errno($ch);
|
||||
$error = curl_error($ch);
|
||||
curl_close($ch);
|
||||
if($errno || empty($data)) {
|
||||
Base::addLog([
|
||||
'url' => $url,
|
||||
'post' => $post,
|
||||
'error' => $error,
|
||||
], 'error_' . $url);
|
||||
return Base::retError($error);
|
||||
} else {
|
||||
if ($isGb2312) {
|
||||
try { $data = iconv('GB2312', 'UTF-8', $data); }catch (Exception $e) { }
|
||||
}
|
||||
$response = self::ihttp_response_parse($data);
|
||||
Base::addLog([
|
||||
'url' => $url,
|
||||
'post' => $post,
|
||||
'response' => $response,
|
||||
], 'success_' . $url);
|
||||
if ($retRaw === true) {
|
||||
return Base::retSuccess($response['code'], $response);
|
||||
}
|
||||
return Base::retSuccess($response['code'], $response['content']);
|
||||
}
|
||||
}
|
||||
$method = empty($post) ? 'GET' : 'POST';
|
||||
$fdata = "{$method} {$urlset['path']}{$urlset['query']} HTTP/1.1\r\n";
|
||||
$fdata .= "Host: {$urlset['host']}\r\n";
|
||||
if(function_exists('gzdecode')) {
|
||||
$fdata .= "Accept-Encoding: gzip, deflate\r\n";
|
||||
}
|
||||
$fdata .= "Connection: close\r\n";
|
||||
if (!empty($extra) && is_array($extra)) {
|
||||
foreach ($extra as $opt => $value) {
|
||||
if (!Base::strExists($opt, 'CURLOPT_')) {
|
||||
$fdata .= "{$opt}: {$value}\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
//$body = '';
|
||||
if ($post) {
|
||||
if (is_array($post)) {
|
||||
$body = http_build_query($post);
|
||||
} else {
|
||||
$body = urlencode((string)$post);
|
||||
}
|
||||
$fdata .= 'Content-Length: ' . strlen($body) . "\r\n\r\n{$body}";
|
||||
} else {
|
||||
$fdata .= "\r\n";
|
||||
}
|
||||
if($urlset['scheme'] == 'https') {
|
||||
$fp = fsockopen('ssl://' . $urlset['host'], $urlset['port'], $errno, $error);
|
||||
} else {
|
||||
$fp = fsockopen($urlset['host'], $urlset['port'], $errno, $error);
|
||||
}
|
||||
stream_set_blocking($fp, true);
|
||||
stream_set_timeout($fp, $timeout);
|
||||
if (!$fp) {
|
||||
Base::addLog([
|
||||
'url' => $url,
|
||||
'post' => $post,
|
||||
'error' => $error,
|
||||
], 'error_' . $url);
|
||||
return Base::retError( $error);
|
||||
} else {
|
||||
fwrite($fp, $fdata);
|
||||
$content = '';
|
||||
while (!feof($fp))
|
||||
$content .= fgets($fp, 512);
|
||||
fclose($fp);
|
||||
if ($isGb2312) {
|
||||
try { $content = iconv('GB2312', 'UTF-8', $content); }catch (Exception $e) { }
|
||||
}
|
||||
$response = self::ihttp_response_parse($content, true);
|
||||
Base::addLog([
|
||||
'url' => $url,
|
||||
'post' => $post,
|
||||
'response' => $response,
|
||||
], 'success_' . $url);
|
||||
if ($retRaw === true) {
|
||||
return Base::retSuccess($response['code'], $response);
|
||||
}
|
||||
return Base::retSuccess($response['code'], $response['content']);
|
||||
}
|
||||
}
|
||||
|
||||
public static function ihttp_get($url) {
|
||||
return self::ihttp_request($url);
|
||||
}
|
||||
|
||||
public static function ihttp_post($url, $data, $timeout = 60) {
|
||||
$headers = array('Content-Type' => 'application/x-www-form-urlencoded');
|
||||
return self::ihttp_request($url, $data, $headers, $timeout);
|
||||
}
|
||||
|
||||
public static function ihttp_proxy($url, $post = [], $timeout = 20, $extra = []) {
|
||||
return self::ihttp_request($url, $post, $extra, $timeout);
|
||||
}
|
||||
|
||||
private static function ihttp_response_parse($data, $chunked = false) {
|
||||
$rlt = array();
|
||||
$pos = strpos($data, "\r\n\r\n");
|
||||
if (Base::strExists(substr($data, 0, $pos), "Proxy-agent:")) {
|
||||
$data = substr($data, $pos + 4, strlen($data));
|
||||
$pos = strpos($data, "\r\n\r\n");
|
||||
}
|
||||
$split1[0] = substr($data, 0, $pos);
|
||||
$split1[1] = substr($data, $pos + 4, strlen($data));
|
||||
|
||||
$split2 = explode("\r\n", $split1[0], 2);
|
||||
preg_match('/^(\S+) (\S+) (\S+)$/', $split2[0], $matches);
|
||||
$rlt['code'] = $matches[2];
|
||||
$rlt['status'] = $matches[3];
|
||||
$rlt['responseline'] = $split2[0];
|
||||
$header = explode("\r\n", $split2[1]);
|
||||
$isgzip = false;
|
||||
$ischunk = false;
|
||||
foreach ($header as $v) {
|
||||
$row = explode(':', $v);
|
||||
$key = trim($row[0]);
|
||||
$value = trim(substr($v, strlen($row[0]) + 1));
|
||||
if (is_array($rlt['headers'][$key])) {
|
||||
$rlt['headers'][$key][] = $value;
|
||||
} elseif (!empty($rlt['headers'][$key])) {
|
||||
$temp = $rlt['headers'][$key];
|
||||
unset($rlt['headers'][$key]);
|
||||
$rlt['headers'][$key][] = $temp;
|
||||
$rlt['headers'][$key][] = $value;
|
||||
} else {
|
||||
$rlt['headers'][$key] = $value;
|
||||
}
|
||||
if(!$isgzip && strtolower($key) == 'content-encoding' && strtolower($value) == 'gzip') {
|
||||
$isgzip = true;
|
||||
}
|
||||
if(!$ischunk && strtolower($key) == 'transfer-encoding' && strtolower($value) == 'chunked') {
|
||||
$ischunk = true;
|
||||
}
|
||||
}
|
||||
if($chunked && $ischunk) {
|
||||
$rlt['content'] = self::ihttp_response_parse_unchunk($split1[1]);
|
||||
} else {
|
||||
$rlt['content'] = $split1[1];
|
||||
}
|
||||
if($isgzip && function_exists('gzdecode')) {
|
||||
$rlt['content'] = gzdecode($rlt['content']);
|
||||
}
|
||||
|
||||
$rlt['meta'] = $data;
|
||||
if($rlt['code'] == '100') {
|
||||
return self::ihttp_response_parse($rlt['content']);
|
||||
}
|
||||
return $rlt;
|
||||
}
|
||||
|
||||
private static function ihttp_response_parse_unchunk($str = null) {
|
||||
if(!is_string($str) or strlen($str) < 1) {
|
||||
return false;
|
||||
}
|
||||
$eol = "\r\n";
|
||||
$add = strlen($eol);
|
||||
$tmp = $str;
|
||||
$str = '';
|
||||
do {
|
||||
$tmp = ltrim($tmp);
|
||||
$pos = strpos($tmp, $eol);
|
||||
if($pos === false) {
|
||||
return false;
|
||||
}
|
||||
$len = hexdec(substr($tmp, 0, $pos));
|
||||
if(!is_numeric($len) or $len < 0) {
|
||||
return false;
|
||||
}
|
||||
$str .= substr($tmp, ($pos + $add), $len);
|
||||
$tmp = substr($tmp, ($len + $pos + $add));
|
||||
$check = trim($tmp);
|
||||
} while(!empty($check));
|
||||
unset($tmp);
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载文件到服务器本地
|
||||
* @param string $url 下载地址
|
||||
* @param string $fileFile 保存文件路径
|
||||
* @return array
|
||||
*/
|
||||
public static function download(string $url, string $fileFile)
|
||||
{
|
||||
if ($url == '') {
|
||||
return Base::retError("url error");
|
||||
}
|
||||
|
||||
// 获取远程文件资源
|
||||
$ch = curl_init();
|
||||
$timeout = 30;
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
|
||||
$file = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
// 保存文件
|
||||
$res = fopen($fileFile, 'a');
|
||||
fwrite($res, $file);
|
||||
fclose($res);
|
||||
|
||||
return Base::retSuccess('success');
|
||||
}
|
||||
}
|
8469
app/Module/IpAddr/all_cn.txt
Normal file
8469
app/Module/IpAddr/all_cn.txt
Normal file
File diff suppressed because it is too large
Load Diff
71
app/Tasks/AbstractTask.php
Normal file
71
app/Tasks/AbstractTask.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
namespace App\Tasks;
|
||||
|
||||
use Hhxsv5\LaravelS\Swoole\Task\Task;
|
||||
|
||||
/**
|
||||
* Class AbstractTask
|
||||
* @package App\Tasks
|
||||
*/
|
||||
abstract class AbstractTask extends Task
|
||||
{
|
||||
protected $newTask = [];
|
||||
|
||||
/**
|
||||
* 添加完成后执行的任务
|
||||
* @param $task
|
||||
*/
|
||||
final protected function addTask($task)
|
||||
{
|
||||
$this->newTask[] = $task;
|
||||
}
|
||||
|
||||
/**
|
||||
* 包装执行过程
|
||||
*/
|
||||
final public function handle()
|
||||
{
|
||||
try {
|
||||
$this->start();
|
||||
} catch (\Exception $e) {
|
||||
$this->info($e);
|
||||
$this->failed($e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始执行任务
|
||||
*/
|
||||
abstract public function start();
|
||||
|
||||
/**
|
||||
* 任务完成事件
|
||||
*/
|
||||
public function finish()
|
||||
{
|
||||
foreach ($this->newTask AS $task) {
|
||||
Task::deliver($task);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务失败事件
|
||||
* @param $e
|
||||
*/
|
||||
public function failed($e)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加日志
|
||||
* @param $var
|
||||
*/
|
||||
private function info($var)
|
||||
{
|
||||
if (!config('app.debug') || defined('DO_NOT_ADD_LOGS')) {
|
||||
return;
|
||||
}
|
||||
info($var);
|
||||
}
|
||||
}
|
67
app/Tasks/IhttpTask.php
Normal file
67
app/Tasks/IhttpTask.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
namespace App\Tasks;
|
||||
|
||||
@error_reporting(E_ALL & ~E_NOTICE);
|
||||
|
||||
use App\Module\Base;
|
||||
use App\Module\Ihttp;
|
||||
|
||||
/**
|
||||
* Ihttp任务
|
||||
* Class IhttpTask
|
||||
* @package App\Tasks
|
||||
*/
|
||||
class IhttpTask extends AbstractTask
|
||||
{
|
||||
protected $url;
|
||||
protected $post;
|
||||
protected $extra;
|
||||
protected $apiWebsocket;
|
||||
protected $apiUserid;
|
||||
|
||||
/**
|
||||
* IhttpTask constructor.
|
||||
* @param $url
|
||||
* @param array $post
|
||||
* @param array $extra
|
||||
*/
|
||||
public function __construct($url, $post = [], $extra = [])
|
||||
{
|
||||
$this->url = $url;
|
||||
$this->post = $post;
|
||||
$this->extra = $extra;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $apiWebsocket
|
||||
*/
|
||||
public function setApiWebsocket($apiWebsocket): void
|
||||
{
|
||||
$this->apiWebsocket = $apiWebsocket;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $apiUserid
|
||||
*/
|
||||
public function setApiUserid($apiUserid): void
|
||||
{
|
||||
$this->apiUserid = $apiUserid;
|
||||
}
|
||||
|
||||
public function start()
|
||||
{
|
||||
$res = Ihttp::ihttp_request($this->url, $this->post, $this->extra);
|
||||
if ($this->apiWebsocket && $this->apiUserid) {
|
||||
$body = Base::isSuccess($res) ? Base::json2array($res['data']) : $res;
|
||||
PushTask::push([
|
||||
'userid' => $this->apiUserid,
|
||||
'msg' => [
|
||||
'messageType' => 'apiWebsocket',
|
||||
'apiWebsocket' => $this->apiWebsocket,
|
||||
'apiSuccess' => Base::isSuccess($res),
|
||||
'body' => $body,
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
167
app/Tasks/PushTask.php
Normal file
167
app/Tasks/PushTask.php
Normal file
@ -0,0 +1,167 @@
|
||||
<?php
|
||||
namespace App\Tasks;
|
||||
|
||||
@error_reporting(E_ALL & ~E_NOTICE);
|
||||
|
||||
use App\Models\WebSocket;
|
||||
use App\Models\WebSocketTmpMsg;
|
||||
use App\Module\Base;
|
||||
use Cache;
|
||||
use Carbon\Carbon;
|
||||
use Hhxsv5\LaravelS\Swoole\Task\Task;
|
||||
|
||||
/**
|
||||
* 发送消息任务
|
||||
* Class PushTask
|
||||
* @package App\Tasks
|
||||
*/
|
||||
class PushTask extends AbstractTask
|
||||
{
|
||||
protected $params;
|
||||
|
||||
/**
|
||||
* PushTask constructor.
|
||||
* @param string|array $params
|
||||
*/
|
||||
public function __construct($params = [])
|
||||
{
|
||||
$this->params = $params;
|
||||
}
|
||||
|
||||
public function start()
|
||||
{
|
||||
if (is_string($this->params)) {
|
||||
$key = $this->params;
|
||||
$params = Cache::pull($key);
|
||||
if (is_array($params) && $params['fd']) {
|
||||
$this->params = [$params];
|
||||
}
|
||||
}
|
||||
is_array($this->params) && self::push($this->params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录发送失败的消息,等上线后重新发送
|
||||
* @param array $userFail
|
||||
* @param array $msg
|
||||
*/
|
||||
private static function addTmpMsg(array $userFail, array $msg)
|
||||
{
|
||||
foreach ($userFail as $uid) {
|
||||
$msgString = Base::array2json($msg);
|
||||
$inArray = [
|
||||
'md5' => md5($uid . '-' . $msgString),
|
||||
'msg' => $msgString,
|
||||
'send' => 0,
|
||||
'create_id' => $uid,
|
||||
'created_at' => Carbon::now(),
|
||||
'updated_at' => Carbon::now(),
|
||||
];
|
||||
if (!WebSocketTmpMsg::whereMd5($inArray['md5'])->exists()) {
|
||||
WebSocketTmpMsg::insertOrIgnore($inArray);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据会员ID重试发送失败的消息
|
||||
* @param $userid
|
||||
*/
|
||||
public static function resendTmpMsgForUserid($userid)
|
||||
{
|
||||
|
||||
$lists = WebSocketTmpMsg::whereCreateId($userid)
|
||||
->whereSend(0)
|
||||
->where('created_at', '>', Carbon::now()->subMinute()) // 1分钟内添加的数据
|
||||
->orderBy('id')
|
||||
->get();
|
||||
if ($lists->isNotEmpty()) {
|
||||
foreach ($lists as $item) {
|
||||
self::push([
|
||||
'tmp_msg_id' => $item->id,
|
||||
'userid' => $userid,
|
||||
'msg' => Base::json2array($item->msg),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 推送消息
|
||||
* @param array $lists 消息列表
|
||||
* @param string|int $key 延迟推送key依据,留空立即推送(延迟推送时发给同一人同一种消息类型只发送最新的一条)
|
||||
* @param int $delay 延迟推送时间,默认:1秒($key填写时有效)
|
||||
*/
|
||||
public static function push(array $lists, $key = '', $delay = 1)
|
||||
{
|
||||
if (!is_array($lists) || empty($lists)) {
|
||||
return;
|
||||
}
|
||||
if (!Base::isTwoArray($lists)) {
|
||||
$lists = [$lists];
|
||||
}
|
||||
$swoole = app('swoole');
|
||||
foreach ($lists AS $item) {
|
||||
if (!is_array($item) || empty($item)) {
|
||||
continue;
|
||||
}
|
||||
$userid = $item['userid'];
|
||||
$fd = $item['fd'];
|
||||
$msg = $item['msg'];
|
||||
$tmp_msg_id = intval($item['tmp_msg_id']);
|
||||
if (!is_array($msg)) {
|
||||
continue;
|
||||
}
|
||||
$messageType = $msg['messageType'];
|
||||
if (empty($messageType)) {
|
||||
continue;
|
||||
}
|
||||
// 发送对象
|
||||
$userFail = [];
|
||||
$array = [];
|
||||
if ($fd) {
|
||||
if (is_array($fd)) {
|
||||
$array = array_merge($array, $fd);
|
||||
} else {
|
||||
$array[] = $fd;
|
||||
}
|
||||
}
|
||||
if ($userid) {
|
||||
if (!is_array($userid)) {
|
||||
$userid = [$userid];
|
||||
}
|
||||
foreach ($userid as $uid) {
|
||||
$row = WebSocket::select(['fd'])->whereUserid($uid)->pluck('fd');
|
||||
if ($row->isNotEmpty()) {
|
||||
$array = array_merge($array, $row->toArray());
|
||||
} else {
|
||||
$userFail[] = $uid;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 开始发送
|
||||
foreach ($array as $fid) {
|
||||
if (empty($key)) {
|
||||
try {
|
||||
$swoole->push($fid, Base::array2json($msg));
|
||||
$tmp_msg_id > 0 && WebSocketTmpMsg::whereId($tmp_msg_id)->update(['send' => 1]);
|
||||
} catch (\Exception $e) {
|
||||
$userFail[] = WebSocket::whereFd($fid)->value('userid');
|
||||
}
|
||||
} else {
|
||||
$key = "PUSH::" . $fid . ":" . $messageType . ":" . $key;
|
||||
Cache::put($key, [
|
||||
'fd' => $fid,
|
||||
'msg' => $msg,
|
||||
]);
|
||||
$task = new PushTask($key);
|
||||
$task->delay($delay);
|
||||
Task::deliver($task);
|
||||
}
|
||||
}
|
||||
// 记录发送失败的
|
||||
$userFail = array_values(array_unique($userFail));
|
||||
$tmp_msg_id == 0 && self::addTmpMsg($userFail, $msg);
|
||||
}
|
||||
}
|
||||
}
|
@ -18,7 +18,11 @@
|
||||
"madnest/madzipper": "^v1.0.5",
|
||||
"mews/captcha": "^3.2.0",
|
||||
"predis/predis": "^1.1.6",
|
||||
"ext-json": "*"
|
||||
"ext-json": "*",
|
||||
"ext-simplexml": "*",
|
||||
"ext-libxml": "*",
|
||||
"ext-gd": "*",
|
||||
"ext-curl": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"barryvdh/laravel-ide-helper": "^2.8.1",
|
||||
|
Loading…
x
Reference in New Issue
Block a user