chuan 2 months ago
parent
commit
3a82434abd
  1. 179
      app/admin/controller/Index.php
  2. 19
      app/admin/controller/Notice.php
  3. 4
      app/admin/controller/Test.php
  4. 99
      app/admin/controller/Upload.php
  5. 15
      app/admin/route/app.php
  6. 82
      app/admin/service/AdminService.php
  7. 10
      app/admin/service/AgentService.php
  8. 95
      app/admin/service/UserService.php
  9. 7
      app/home/route/app.php
  10. 71
      app/home/service/LoginService.php
  11. 101
      app/home/service/UserVerifyService.php
  12. 2
      app/home/validate/LoginValidate.php
  13. 40
      app/utility/AwsS3Handler.php
  14. 79
      app/utility/Pusher.php
  15. 3
      composer.json
  16. 50
      composer.lock
  17. 4
      vendor/composer/autoload_files.php
  18. 1
      vendor/composer/autoload_psr4.php
  19. 9
      vendor/composer/autoload_static.php
  20. 51
      vendor/composer/installed.json
  21. 13
      vendor/composer/installed.php
  22. 26
      vendor/pusher/pusher-push-notifications/CHANGELOG.md
  23. 21
      vendor/pusher/pusher-push-notifications/LICENSE
  24. 25
      vendor/pusher/pusher-push-notifications/composer.json
  25. 220
      vendor/pusher/pusher-push-notifications/src/PushNotifications.php
  26. 2
      vendor/services.php

179
app/admin/controller/Index.php

@ -4,6 +4,8 @@ namespace app\admin\controller;
use app\admin\service\AdminBaseService;
use app\admin\service\setting\IPOService;
use app\model\AdminModel;
use app\model\AuthRoleModel;
use app\model\BrokerageSettingModel;
use app\model\ContractListMode;
use app\model\ContractTradeModel;
@ -12,12 +14,6 @@ use app\model\DigitalTradeModel;
use app\model\DrawalSettingModel;
use app\model\FeeSettingModel;
use app\model\ForexListModel;
use app\model\PreIdnStockModel;
use app\model\PreInStockModel;
use app\model\PreMysStockModel;
use app\model\PreSgdStockModel;
use app\model\PreThaStockModel;
use app\model\PreUsStockModel;
use app\model\RechargeApplyModel;
use app\model\StockBrlListModel;
use app\model\StockEurListModel;
@ -39,25 +35,8 @@ use app\model\StockSgdListModel;
use app\model\StockThaListModel;
use app\model\StockThaTradeModel;
use app\model\StockTradeModel;
use app\model\UserIdnPreStockOrderModel;
use app\model\UserInPreStockOrderModel;
use app\model\UserModel;
use app\model\UserMysPreStockOrderModel;
use app\model\UserSgdPreStockOrderModel;
use app\model\UserStockIdnLogModel;
use app\model\UserStockIdnModel;
use app\model\UserStockInLogModel;
use app\model\UserStockInModel;
use app\model\UserStockLogModel;
use app\model\UserStockModel;
use app\model\UserStockMysLogModel;
use app\model\UserStockMysModel;
use app\model\UserStockSgdLogModel;
use app\model\UserStockSgdModel;
use app\model\UserStockThaLogModel;
use app\model\UserStockThaModel;
use app\model\UserThaPreStockOrderModel;
use app\model\UserUsPreStockOrderModel;
use app\model\UserVerifyLogModel;
use app\model\UserWithdrawalModel;
use app\utility\ClientGo;
use think\facade\Db;
@ -84,68 +63,126 @@ class Index extends AdminBaseController
$userWithdrawTableName = $prefix . (new UserWithdrawalModel())->getName();
// 总注册人数(用户的总数)
$totalRegisterNum = Db::table($userTableName)->count();
// 获取当登录账号信息
$adminId = $this->request->user_id;
$account = AdminModel::where('id', $adminId)->find();
if (empty($account)) {
return json(['code' => '500', 'message' => '当前账号数据为空', 'data' => []]);
}
// 查询当前账号的角色信息
$role = AuthRoleModel::where(['id'=>$account->role_id])->find();
if (empty($role)) {
return json(['code' => '500', 'message' => '当前账号分配的角色数据为空', 'data' => []]);
}
$today = date('Y-m-d'); // 今天凌晨
$tomorrow = date('Y-m-d', strtotime('tomorrow')); // 明天凌晨
$whereInUser = [];
// 根据角色获取数据统计范围
switch ($role->name) {
case AuthRoleModel::NAME_ADMIN: // 超级管理员可以查看所有数据
// 今日注册用户
$todayRegisterNum = UserModel::whereTime('create_time', 'between', [$today, $tomorrow])->count();
// 总注册人数(用户的总数)
$totalRegisterNum = UserModel::count();
// // 今日充值用户 完成状态
// $todayRechargeNum = RechargeApplyModel::where('status', 1)->whereTime('create_time', 'between', [$today, $tomorrow])->group('user_id')->count();
// 总充值用户(充值用户的个数 以用户id分组)
// $totalRechargeNum = RechargeApplyModel::where('status', 1)->group('user_id')->count();
break;
case AuthRoleModel::NAME_AGENT: // 代理 - 查看代理下可以查看的用户
// 今日注册用户
$todayRegisterNum = UserModel::whereTime('create_time', 'between', [$today, $tomorrow])->where('agent_id', $adminId)->count();
// 总注册人数(用户的总数)
$userIds = UserModel::where('agent_id', $adminId)->column('user_id');
$totalRegisterNum = count($userIds);
$whereInUser[] = ['user_id', 'in', $userIds];
break;
case AuthRoleModel::NAME_DIRECTOR: // 总监 - 查询总监下可以查看的用户
$customerIds = [];
$teamHeaderIds = AdminModel::where('parent_id', $adminId)->column('id'); // 总监下面的组长ID
if (!empty($teamHeaderIds)) {
$customerIds = AdminModel::whereIn('parent_id', $teamHeaderIds)->column('id'); // 组长下面的ID
}
// 今日注册用户
$todayRegisterNum = UserModel::whereTime('create_time', 'between', [$today, $tomorrow])->whereIn('customer_id', $customerIds)->count();
// 总注册人数(用户的总数)
$userIds = UserModel::whereIn('customer_id', $customerIds)->column('user_id');
$totalRegisterNum = count($userIds);
$whereInUser[] = ['user_id', 'in', $userIds];
break;
case AuthRoleModel::NAME_TEAM_HEADER: // 组长 - 查看组长下可以查看的用户
$customerIds = AdminModel::where('parent_id', $adminId)->column('id'); // 组长下面的客服ID
// 今日注册用户
$todayRegisterNum = UserModel::whereTime('create_time', 'between', [$today, $tomorrow])->whereIn('customer_id', $customerIds)->count();
// 总注册人数(用户的总数)
$userIds = UserModel::whereIn('customer_id', $customerIds)->column('user_id');
$totalRegisterNum = count($userIds);
$whereInUser[] = ['user_id', 'in', $userIds];
break;
case AuthRoleModel::NAME_CUSTOMER: // 客服 - 查看客服下的用户
// 今日注册用户
$todayRegisterNum = UserModel::whereTime('create_time', 'between', [$today, $tomorrow])->where('customer_id', $adminId)->count();
// 总注册人数(用户的总数)
$userIds = UserModel::where('customer_id', $adminId)->column('user_id');
$totalRegisterNum = count($userIds);
$whereInUser[] = ['user_id', 'in', $userIds];
break;
default:
return json(['code' => '500', 'message' => '当前角色未知,不能提供数据统计', 'data' => []]);
}
// 今日充值用户 完成状态
$todayRechargeNum = RechargeApplyModel::where('status', 1)->whereTime('create_time', 'between', [$today, $tomorrow])->where($whereInUser)->group('user_id')->count();
// 总充值用户(充值用户的个数 以用户id分组)
$totalRechargeNum = Db::table($rechargeApplyTableName)->where('status', 1)->group('user_id')->count();
$totalRechargeNum = RechargeApplyModel::where('status', 1)->where($whereInUser)->group('user_id')->count();
// 总交易用户(合约 股票 现货 交易的用户去重 订单状态为持仓 和 完成 订单)
$contractTradeUserId = Db::table($ContractTradeTableName)->where('status', 'in', [1, 3])->distinct(true)->column('user_id');
$stockTradeUserId = Db::table($stockTradeTableName)->where('status', 'in', [1, 3])->distinct(true)->column('user_id');
$stockMysTradeUserId = Db::table($stockMysTradeTableName)->where('status', 'in', [1, 3])->distinct(true)->column('user_id');
$stockThaTradeUserId = Db::table($stockThaTradeTableName)->where('status', 'in', [1, 3])->distinct(true)->column('user_id');
$stockIdnTradeUserId = Db::table($stockIdnTradeTableName)->where('status', 'in', [1, 3])->distinct(true)->column('user_id');
$stockInTradeUserId = Db::table($stockInTradeTableName)->where('status', 'in', [1, 3])->distinct(true)->column('user_id');
$digitalTradeUserId = Db::table($digitalTradeTableName)->where('status', 'in', [1, 3])->distinct(true)->column('user_id');
$contractTradeUserId = Db::table($ContractTradeTableName)->where('status', 'in', [1, 3])->where($whereInUser)->distinct(true)->column('user_id');
$stockTradeUserId = Db::table($stockTradeTableName)->where('status', 'in', [1, 3])->where($whereInUser)->distinct(true)->column('user_id');
$stockMysTradeUserId = Db::table($stockMysTradeTableName)->where('status', 'in', [1, 3])->where($whereInUser)->distinct(true)->column('user_id');
$stockThaTradeUserId = Db::table($stockThaTradeTableName)->where('status', 'in', [1, 3])->where($whereInUser)->distinct(true)->column('user_id');
$stockIdnTradeUserId = Db::table($stockIdnTradeTableName)->where('status', 'in', [1, 3])->where($whereInUser)->distinct(true)->column('user_id');
$stockInTradeUserId = Db::table($stockInTradeTableName)->where('status', 'in', [1, 3])->where($whereInUser)->distinct(true)->column('user_id');
$digitalTradeUserId = Db::table($digitalTradeTableName)->where('status', 'in', [1, 3])->where($whereInUser)->distinct(true)->column('user_id');
$totalArrayMerge = array_unique(array_merge($contractTradeUserId, $stockTradeUserId, $digitalTradeUserId, $stockMysTradeUserId, $stockIdnTradeUserId, $stockThaTradeUserId, $stockInTradeUserId));
$totalTradeNum = count($totalArrayMerge);
// 总提现用户(以用户id 分组查询数量)
$totalWithdrawalNum = Db::table($userWithdrawTableName)->group('user_id')->count();
$totalWithdrawalNum = Db::table($userWithdrawTableName)->where($whereInUser)->group('user_id')->count();
// 总充值金额 充值完成
$totalRechargeAmount = Db::table($rechargeApplyTableName)->where('status', 1)->sum('recharge_num');
$totalRechargeAmount = Db::table($rechargeApplyTableName)->where($whereInUser)->where('status', 1)->sum('recharge_num');
// 总提款金额 提款完成
$totalWithdrawAmount = Db::table($userWithdrawTableName)->where('status', 2)->sum('apply_num');
$totalWithdrawAmount = Db::table($userWithdrawTableName)->where($whereInUser)->where('status', 2)->sum('apply_num');
// 今日注册用户
$today = date('Y-m-d'); // 今天凌晨
$tomorrow = date('Y-m-d', strtotime('tomorrow')); // 明天凌晨
$todayRegisterNum = Db::table($userTableName)->whereTime('create_time', 'between', [$today, $tomorrow])->count();
// 今日充值用户 完成状态
$todayRechargeNum = Db::table($userTableName)->where('status', 1)
->whereTime('create_time', 'between', [$today, $tomorrow])
->group('user_id')->count();
// 今日交易用户
// 合约
$todayContractTradeUserId = Db::table($ContractTradeTableName)->where('status', 'in', [1, 3])
->whereTime('create_time', 'between', [$today, $tomorrow])
->whereTime('create_time', 'between', [$today, $tomorrow])->where($whereInUser)
->distinct(true)->column('user_id');
//股票
$todayStockTradeUserId = Db::table($stockTradeTableName)->where('status', 'in', [1, 3])
->whereTime('create_time', 'between', [$today, $tomorrow])
->whereTime('create_time', 'between', [$today, $tomorrow])->where($whereInUser)
->distinct(true)->column('user_id');
$todayStockMysTradeUserId = Db::table($stockMysTradeTableName)->where('status', 'in', [1, 3])
->whereTime('create_time', 'between', [$today, $tomorrow])
->whereTime('create_time', 'between', [$today, $tomorrow])->where($whereInUser)
->distinct(true)->column('user_id');
$todayStockThaTradeUserId = Db::table($stockThaTradeTableName)->where('status', 'in', [1, 3])
->whereTime('create_time', 'between', [$today, $tomorrow])
->whereTime('create_time', 'between', [$today, $tomorrow])->where($whereInUser)
->distinct(true)->column('user_id');
$todayStockIndTradeUserId = Db::table($stockIdnTradeTableName)->where('status', 'in', [1, 3])
->whereTime('create_time', 'between', [$today, $tomorrow])
->whereTime('create_time', 'between', [$today, $tomorrow])->where($whereInUser)
->distinct(true)->column('user_id');
$todayStockInTradeUserId = Db::table($stockInTradeTableName)->where('status', 'in', [1, 3])
->whereTime('create_time', 'between', [$today, $tomorrow])
->whereTime('create_time', 'between', [$today, $tomorrow])->where($whereInUser)
->distinct(true)->column('user_id');
// 现货
$todayDigitalTradeUserId = Db::table($digitalTradeTableName)->where('status', 'in', [1, 3])
->whereTime('create_time', 'between', [$today, $tomorrow])
->whereTime('create_time', 'between', [$today, $tomorrow])->where($whereInUser)
->distinct(true)->column('user_id');
// 计算总数
@ -154,39 +191,53 @@ class Index extends AdminBaseController
// 今日提款用户
$todayWithdrawNum = Db::table($userWithdrawTableName)
->whereTime('create_time', 'between', [$today, $tomorrow])
->whereTime('create_time', 'between', [$today, $tomorrow])->where($whereInUser)
->group('user_id')->count();
// 今日充值金额 完成状态
$todayRechargeAmount = Db::table($rechargeApplyTableName)
->whereTime('create_time', 'between', [$today, $tomorrow])
->whereTime('create_time', 'between', [$today, $tomorrow])->where($whereInUser)
->where('status', 1)->sum('recharge_num');
// 今日提款金额 完成状态
$todayWithdrawAmount = Db::table($userWithdrawTableName)
->whereTime('create_time', 'between', [$today, $tomorrow])
->whereTime('create_time', 'between', [$today, $tomorrow])->where($whereInUser)
->where('status', 2)->sum('apply_num');
// 等待处理充值订单数量
$pendingRecharge = RechargeApplyModel::where('status', 0)->where($whereInUser)->count();
// 等待处理提款订单数量
$pendingWithdraw = UserWithdrawalModel::where('status', 4)->where($whereInUser)->count();
// 等待实名审核数量
$pendingUserVerify = UserVerifyLogModel::where('status', 1)->where($whereInUser)->count();
$data = [
'todayRegisterNum' => $todayRegisterNum, // 今日注册用户
'totalRegisterNum' => $totalRegisterNum, // 总注册人数
'totalRechargeNum' => $totalRechargeNum,// 总充值用户
'totalTradeNum' => $totalTradeNum,// 总交易用户
'totalWithdrawalNum' => $totalWithdrawalNum,// 总提现用户
'totalRechargeAmount' => $totalRechargeAmount,// 总充值金额
'totalWithdrawAmount' => $totalWithdrawAmount, // 总提款金额
'todayRegisterNum' => $todayRegisterNum, // 今日注册用户
'todayRechargeNum' => $todayRechargeNum, // 今日充值用户
'totalRechargeNum' => $totalRechargeNum,// 总充值用户
'todayTradeNum' => $todayTradeNum, // 今日交易用户
'totalTradeNum' => $totalTradeNum,// 总交易用户
'todayWithdrawNum' => $todayWithdrawNum, // 今日提款用户
'totalWithdrawalNum' => $totalWithdrawalNum,// 总提现用户
'todayRechargeAmount' => $todayRechargeAmount, // 今日充值金额
'totalRechargeAmount' => $totalRechargeAmount,// 总充值金额
'todayWithdrawAmount' => $todayWithdrawAmount, // 今日提款金额
'totalWithdrawAmount' => $totalWithdrawAmount, // 总提款金额
'no_deal_recharge' => $pendingRecharge, // 等待处理充值订单数量
'no_deal_withdraw' => $pendingWithdraw, // 等待处理提款订单数量
'no_deal_real' => $pendingUserVerify, // 等待实名审核数量
];
return json(['code' => '0', 'message' => 'SUCCESS', 'data' => $data]);
} catch (\Exception $exception) {
return json(['code' => '1', 'message' => '系统繁忙']);
return json(['code' => '1', 'message' => '系统繁忙', [$exception->getMessage(), $exception->getTrace()]]);
}
}

19
app/admin/controller/Notice.php

@ -12,4 +12,23 @@ class Notice extends AdminBaseController
$returnData = (new NoticeService())->popUp($this->request->param());
return json($returnData);
}
// 使用Pusher服务推送系统消息
public function pushMessage()
{
$param = $this->request->param();
if (empty($param['title']) || empty($param['body'])) {
return json([
'code' => 400,
'message' => "缺少参数",
'data' => []
]);
}
$interestName = ["admin-popup-push"]; // 订阅兴趣的名称, 一次推送最多100个兴趣名称
$title = "";
$body = "";
$res = (new \app\utility\Pusher())->publishToInterest($interestName, $title, $body);
return json($res);
}
}

4
app/admin/controller/Test.php

@ -1,6 +1,10 @@
<?php
namespace app\admin\controller;
use app\model\AdminModel;
use app\model\UserAccessLogModel;
use app\model\UserModel;
class Test extends AdminBaseController
{
public function index()

99
app/admin/controller/Upload.php

@ -4,6 +4,7 @@ namespace app\admin\controller;
use app\model\AwsS3Model;
use app\model\FileModel;
use app\utility\AwsS3Handler;
use Aws\S3\S3Client;
use think\facade\Filesystem;
use think\facade\Config;
@ -11,8 +12,23 @@ use think\facade\Log;
class Upload extends AdminBaseController
{
// 上传图片
public function upload()
// 上传文件至服务器本地
public function uploadToServer()
{
$file = $this->request->file('file');
if (!$file) {
return json(['code' => 400, 'message' => 'No file uploaded233']);
}
if ($file->getSize() > 100 * 1024 * 1024) {
return json(['code' => 400, 'message' => 'Upload file is too large']);
}
$name = Filesystem::disk('local')->putFile('topic', $file);
$path = '/bs/image/'.$name;
return json(['code'=>0, 'message'=>'ok', 'data'=>['path'=>$path]]);
}
// 上传图片至 aws s3
public function uploadImg()
{
try {
// 获取文件
@ -39,35 +55,22 @@ class Upload extends AdminBaseController
$fileName = bin2hex(random_bytes(16)) . '.' . $file->getOriginalExtension();
// 初始化s3客户端
$s3Config = Config::get('common.aws_s3');
$s3Client = new S3Client([
'version' => '2006-03-01',
'region' => $s3Config['aws_region'],
'credentials' => [
'key' => $s3Config['aws_key'],
'secret' => $s3Config['aws_secret'],
],
]);
// 上传文件到S3
$result = $s3Client->putObject([
'Bucket' => $s3Config['aws_bucket'],
'Key' => 'bourse-avatar/' . $fileName, // s3中的存储路径
'Body' => $openFile,
'ContentType' => $file->getOriginalMime(), // 设置文件的MIME, 不然s3会以流式存储
])->toArray();
if (empty($result['ObjectURL'])) {
return json(['code' => 400, 'message' => '上传s3失败']);
$s3Obj = new AwsS3Handler($s3Config);
$keyName = 'bourse-avatar/' . $fileName;
$result = $s3Obj->putObject($keyName, $openFile, $file->getOriginalMime());
fclose($openFile);
if (!isset($result['data']['ObjectURL'])) {
return json(['code' => 400, 'message' => '上传图片至s3失败']);
}
// 记录上传的文件
$resData = AwsS3Model::create([
AwsS3Model::create([
'name' => $fileName,
's3_url' => $result['ObjectURL'],
's3_url' => $result['data']['ObjectURL'],
'size' => $file->getSize(),
'mime' => $file->getOriginalMime(),
'ext' => $file->getOriginalExtension(),
]);
fclose($openFile);
// 返回路径
return json(['code' => '0', 'message' => '上传成功', 'data' => ['path' => $resData->s3_url]]);
return json(['code' => '0', 'message' => '上传成功', 'data' => ['path' => $result['data']['ObjectURL']]]);
} catch (\Exception $exception) {
if (isset($openFile)) {
fclose($openFile);
@ -76,7 +79,7 @@ class Upload extends AdminBaseController
}
}
// 上传视频到aws s3
// 上传视频到 aws s3
public function uploadVideo()
{
try {
@ -100,32 +103,18 @@ class Upload extends AdminBaseController
$fileName = bin2hex(random_bytes(16)) . '.' . $file->getOriginalExtension();
// 初始化s3客户端
$s3Config = Config::get('common.aws_s3');
$s3Client = new S3Client([
// 'version' => 'latest',
'version' => '2006-03-01',
'region' => $s3Config['aws_region'],
'credentials' => [
'key' => $s3Config['aws_key'],
'secret' => $s3Config['aws_secret'],
],
]);
// 上传文件到S3
$result = $s3Client->putObject([
'Bucket' => $s3Config['aws_bucket'],
'Key' => 'bourse-video-node/' . $fileName, // s3中的存储路径
'Body' => $openFile,
'ContentType' => $file->getOriginalMime(), // 设置文件的MIME, 不然s3会以流式存储
// 'ACL' => 'public-read', // 设置文件为公开可读
])->toArray();
$s3Obj = new AwsS3Handler($s3Config);
$keyName = 'bourse-video-node/' . $fileName;
$result = $s3Obj->putObject($keyName, $openFile, $file->getOriginalMime());
fclose($openFile);
Log::info("上传s3结果:". json_encode($result));
if (empty($result['ObjectURL'])) {
return json(['code' => 400, 'message' => '上传失败']);
if (!isset($result['data']['ObjectURL'])) {
return json(['code' => 400, 'message' => '上传视频至s3失败']);
}
// 记录上传的文件
$resData = AwsS3Model::create([
'name' => $fileName,
's3_url' => $result['ObjectURL'],
's3_url' => $result['data']['ObjectURL'],
'size' => $file->getSize(),
'mime' => $file->getOriginalMime(),
'ext' => $file->getOriginalExtension(),
@ -133,35 +122,17 @@ class Upload extends AdminBaseController
// 返回上传成功的地址
return json(['code' => '0', 'message' => '上传成功', 'data' => [
'id' => $resData->id,
'url' => $result['ObjectURL'],
'url' => $result['data']['ObjectURL'],
'name' => $fileName,
'size' => $file->getSize(),
'mime' => $file->getOriginalMime(),
'ext'=> $file->getOriginalExtension(),
]]);
} catch (\Exception $exception) {
if (isset($openFile)) {
fclose($openFile);
}
return json(['code' => '500', 'message' => '系统繁忙', 'data' => [$exception->getMessage()]]);
}
}
// 上传文件至服务器本地
public function uploadToServer()
{
$file = $this->request->file('file');
if (!$file) {
return json(['code' => 400, 'message' => 'No file uploaded233']);
}
if ($file->getSize() > 100 * 1024 * 1024) {
return json(['code' => 400, 'message' => 'Upload file is too large']);
}
$name = Filesystem::disk('local')->putFile('topic', $file);
$path = '/bs/image/'.$name;
return json(['code'=>0, 'message'=>'ok', 'data'=>['path'=>$path]]);
}
// 创建分段上传,初始化一个新的上传任务,生成一个上传的唯一标识符
public function initiateUpload(){
try {

15
app/admin/route/app.php

@ -16,8 +16,6 @@ Route::post('/test', 'Test/index');
Route::post('/test_upload', 'Upload/uploadVideo');
Route::post('test_api', 'auth.AuthRule/getSideMenu');
Route::group('/', function () {
// 上传图片
Route::post('/upload', 'Upload/upload');
// 国家和地区
Route::post('/country', 'Country/getAll');
// 配置
@ -31,6 +29,7 @@ Route::group('/', function () {
Route::post('config/edit_sms_template', 'Config/editSmsTemplate'); //编辑短信模板
Route::post('notice/popup', 'Notice/popUp'); // 弹窗推送消息
Route::post('notice/push_message', 'Notice/pushMessage'); // 使用Pusher推送系统级通知
// 渠道列表
Route::post('/channel/list', 'Channel/list'); //渠道列表
@ -40,13 +39,16 @@ Route::group('/', function () {
Route::post('/channel/agent_channel_list', 'Channel/agentChannelList'); //代理推广渠道列表
Route::post('/channel/create_agent_channel', 'Channel/createAgentChannel')->middleware('admin_log'); //创建代理推广渠道
// 视频点播相关
Route::post('/upload_video', 'Upload/uploadVideo'); //上传视频到aws s3
// 文件上传
Route::post('/upload', 'Upload/uploadImg'); //上传图片
Route::post('/upload_video', 'Upload/uploadVideo'); //上传视频
Route::post('/initiate_upload', 'Upload/initiateUpload'); //初始化分片上传
Route::post('/upload_part', 'Upload/uploadPart'); //分片上传
Route::post('/complete_upload', 'Upload/completeUpload'); //完成分片上传
Route::post('/abort_upload', 'Upload/abortUpload'); //取消分片上传
Route::post('video_on_demand_list', 'video/videoOnDemandList'); //获取视频点播列表
// 视频点播相关
Route::post('video_on_demand_list', 'video/videoOnDemandList'); //获取视频点播列表
Route::post('add_video', 'video/addVideoOnDemand')->middleware('admin_log'); //添加点播视频
Route::post('edit_video', 'video/editVideoOnDemand')->middleware('admin_log'); //编辑点播视频
@ -64,7 +66,6 @@ Route::group('/', function () {
Route::post('/order/digital_back', 'Order/digitalBack');
Route::post('/order/digital_deal', 'Order/digitalDeal');
// 合约订单
Route::post('/order/contract_hold', 'Order/contractHold');
Route::post('/order/contract_place', 'Order/contractPlace');
@ -76,14 +77,12 @@ Route::group('/', function () {
Route::post('/order/contract_sec_back', 'Order/contractSecBack');
Route::post('/order/contract_sec_clear', 'Order/contractSecClear');
// 外汇订单
Route::post('/order/forex_hold', 'Order/forexHold');
Route::post('/order/forex_place', 'Order/forexPlace');
Route::post('/order/forex_back', 'Order/forexBack');
Route::post('/order/forex_clear', 'Order/forexClear');
// 股票-废弃
// Route::post('/order/stock_hold', 'Order/stockHold');
// Route::post('/order/stock_place', 'Order/stockPlace');

82
app/admin/service/AdminService.php

@ -489,39 +489,49 @@ class AdminService extends AdminBaseService
public function translatorAddCustomer($param)
{
try {
if (empty($param['translator_id']) || empty($param['customer_id'])) {
return $this->toData('400', '缺少参数');
if (empty($param['translator_id'])) {
return $this->toData('400', '缺少翻译员参数');
}
// 记录好友关系
$translatorCustomer = TranslatorCustomerModel::where(['translator_id'=>$param['translator_id'], 'customer_id'=>$param['customer_id']])->find();
if (empty($translatorCustomer)) {
TranslatorCustomerModel::create(['translator_id'=>$param['translator_id'], 'customer_id'=>$param['customer_id']]);
if (empty($param['customer_id_list']) || !is_array($param['customer_id_list'])) {
return $this->toData('400', '缺少客服参数');
}
// 请求聊天服添加好友关系
$translatorChatInfo = UserChatLinkModel::where(['user_id'=>$param['translator_id'], 'user_type'=>UserChatLinkModel::USER_CHAT_LINK_USER_TYPE_ADMIN])->find(); //查询翻译员的聊天账号uuid
// 翻译员的聊天账号信息
$translatorChatInfo = UserChatLinkModel::where(['user_id'=>$param['translator_id'], 'user_type'=>UserChatLinkModel::USER_CHAT_LINK_USER_TYPE_ADMIN])->find();
if (empty($translatorChatInfo)) {
return $this->toData('500', '翻译员的聊条账号信息错误');
}
$customerChatInfo = UserChatLinkModel::where(['user_id'=>$param['customer_id'], 'user_type'=>UserChatLinkModel::USER_CHAT_LINK_USER_TYPE_ADMIN])->find(); //查询客服的聊天账号uuid
if (empty($customerChatInfo)) {
return $this->toData('500', '客服的聊天账号信息错误');
}
$chatFriendsData = [
'UserUuid' => $translatorChatInfo->chat_uuid,
'CustomerUuid' => $customerChatInfo->chat_uuid,
];
$chatFriendsUrl = env('CHAT_SERVER.BASE_URL') . '/api/eachOtherFriends';
$chatFriendsRes = (new \app\utility\RequestChatServer())->ReqChatServer($chatFriendsUrl, $chatFriendsData);
Log::info("翻译员添加客服好友结果:". json_encode($chatFriendsRes));
// 将客服添加到翻译员的聊天群组中
// 翻译员创建的聊天群组信息
$chatGroup = UserChatGroupModel::where(['user_id'=>$param['translator_id'], 'remark'=>UserChatGroupModel::USER_CHAT_GROUP_REMARK_ADMIN_INIT])->find();
if (empty($chatGroup)) {
return $this->toData('500', 'The chat group is error.');
}
$joinChatGroupUrl = env('CHAT_SERVER.BASE_URL') . '/api/group/join/'.$translatorChatInfo->chat_uuid.'/'.$chatGroup->group_uuid;
$joinChatGroupRes = (new \app\utility\RequestChatServer())->ReqChatServer($joinChatGroupUrl, []);
Log::info("翻译员添加客服到聊天群组结果:". json_encode($joinChatGroupRes));
return $this->toData('0', 'SUCCESS', [$joinChatGroupRes]);
foreach ($param['customer_id_list'] as $customerId) {
// 记录好友关系
$translatorCustomer = TranslatorCustomerModel::where(['translator_id'=>$param['translator_id'], 'customer_id'=>$customerId])->find();
if (empty($translatorCustomer)) {
TranslatorCustomerModel::create(['translator_id'=>$param['translator_id'], 'customer_id'=>$customerId]);
}
//查询客服的聊天账号uuid
$customerChatInfo = UserChatLinkModel::where(['user_id'=>$customerId, 'user_type'=>UserChatLinkModel::USER_CHAT_LINK_USER_TYPE_ADMIN])->find();
if (empty($customerChatInfo)) {
return $this->toData('500', '客服的聊天账号信息错误');
}
$chatFriendsData = [
'UserUuid' => $translatorChatInfo->chat_uuid,
'CustomerUuid' => $customerChatInfo->chat_uuid,
];
$chatFriendsUrl = env('CHAT_SERVER.BASE_URL') . '/api/eachOtherFriends';
$chatFriendsRes = (new \app\utility\RequestChatServer())->ReqChatServer($chatFriendsUrl, $chatFriendsData);
Log::info("翻译员添加客服好友结果:". json_encode($chatFriendsRes));
// 将客服添加到翻译员的聊天群组中
$joinChatGroupUrl = env('CHAT_SERVER.BASE_URL') . '/api/group/join/'.$customerChatInfo->chat_uuid.'/'.$chatGroup->group_uuid;
$joinChatGroupRes = (new \app\utility\RequestChatServer())->ReqChatServer($joinChatGroupUrl, []);
Log::info("翻译员添加客服到聊天群组结果:". json_encode($joinChatGroupRes));
}
return $this->toData('0', 'SUCCESS', []);
} catch (\Exception $exception) {
return $this->toData('500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]);
}
@ -658,42 +668,42 @@ class AdminService extends AdminBaseService
case AuthRoleModel::NAME_AGENT: // 代理 - 查看代理下可以查看的用户
$userIds = UserModel::where('agent_id', $adminId)->column('user_id');
if (!empty($param['user_id']) && in_array($param['user_id'], $userIds)) {
$whereUser[] = ['user_id', '=', $userIds];
$whereUser[] = ['user_id', '=', $param['user_id']];
} else {
$whereUser[] = ['user_id', 'in', $userIds];
}
break;
case AuthRoleModel::NAME_DIRECTOR: // 总监 - 查询总监下可以查看的用户
$userIds = [];
$teamHeaders = AdminModel::where('parent_id', $adminId)->find(); // 组长账号
$teamHeaders = AdminModel::where('parent_id', $adminId)->column('id'); // 组长账号
if (!empty($teamHeaders)) {
$customer = AdminModel::where(['parent_id', 'in', $teamHeaders])->find(); // 客服账号
$customer = AdminModel::whereIn('parent_id', $teamHeaders)->column('id'); // 客服账号
if (!empty($customer)) {
$userIds = UserModel::where(['customer_id', 'in', $customer])->column('user_id');
$userIds = UserModel::whereIn('customer_id', $customer)->column('user_id');
}
}
if (!empty($param['user_id']) && in_array($param['user_id'], $userIds)) {
$whereUser[] = ['user_id', '=', $userIds];
$whereUser[] = ['user_id', '=', $param['user_id']];
} else {
$whereUser[] = ['user_id', 'in', $userIds];
}
break;
case AuthRoleModel::NAME_TEAM_HEADER: // 组长 - 查看组长下可以查看的用户
$userIds = [];
$customer = AdminModel::where('parent_id', $adminId)->find();
$customer = AdminModel::where('parent_id', $adminId)->column('id');
if (!empty($customer)) {
$userIds = UserModel::where(['customer_id', 'in', $customer])->column('user_id');
$userIds = UserModel::whereIn('customer_id', $customer)->column('user_id');
}
if (!empty($param['user_id']) && in_array($param['user_id'], $userIds)) {
$whereUser[] = ['user_id', '=', $userIds];
$whereUser[] = ['user_id', '=', $param['user_id']];
} else {
$whereUser[] = ['user_id', 'in', $userIds];
}
break;
case AuthRoleModel::NAME_CUSTOMER: // 客服 - 查看自己操作数据
$userIds = UserModel::where(['customer_id', '=', $adminId])->column('user_id');
case AuthRoleModel::NAME_CUSTOMER: // 客服 - 查看客服下的用户
$userIds = UserModel::where(['customer_id' => $adminId])->column('user_id');
if (!empty($param['user_id']) && in_array($param['user_id'], $userIds)) {
$whereUser[] = ['user_id', '=', $userIds];
$whereUser[] = ['user_id', '=', $param['user_id']];
} else {
$whereUser[] = ['user_id', 'in', $userIds];
}
@ -706,7 +716,7 @@ class AdminService extends AdminBaseService
if (!empty($param['module'])) {
$where['module'] = $param['module'];
}
$list = UserAccessLogModel::where($whereUser)->where($where)->order('id', 'desc')->paginate([
$list = UserAccessLogModel::where($where)->where($whereUser)->order('id', 'desc')->paginate([
'list_rows' => $param['limit'],
'page' => $param['page'],
]);

10
app/admin/service/AgentService.php

@ -11,6 +11,7 @@ use app\model\PurchaseVipModel;
use app\model\RechargeApplyModel;
use app\model\StockJpTradeModel;
use app\model\StockTradeModel;
use app\model\UserChatGroupModel;
use app\model\UserChatLinkModel;
use app\model\UserModel;
use app\model\UserWithdrawalModel;
@ -401,11 +402,17 @@ class AgentService extends AdminBaseService
if (empty($param['agent_id'])) {
return $this->toData('400', 'Missing param agent_id');
}
//判断一个代理下只能有一个推流配置
// 判断一个代理下只能有一个推流配置
$ckInfo = AwsIvsModel::where('agent_id', $param['agent_id'])->find();
if ($ckInfo) {
return $this->toData('500', '一个代理下只能配置一个推流信息');
}
// 获取代理的聊天群组
$chatGroup = UserChatGroupModel::where(['user_id'=>$param['agent_id'], 'remark'=>'admin_init'])->find();
if (empty($chatGroup)) {
return $this->toData('500', '当前代理没有聊天群组');
}
//保存推流配置
$res = AwsIvsModel::create([
'title' => $param['title'],
@ -416,6 +423,7 @@ class AgentService extends AdminBaseService
'secret_key' => $param['secret_key'],
'play_url' => $param['play_url'],
'agent_id' => $param['agent_id'],
'agent_chat_group_id' => $chatGroup->group_uuid,
'ad_content' => $param['ad_content'] ?? "",
'state' => $param['state'] ?? 1,
]);

95
app/admin/service/UserService.php

@ -68,26 +68,27 @@ class UserService extends AdminBaseService
return $this->toData('500', '当前账号分配的角色为空');
}
$whereRole = [];
switch ($role->name) {
case AuthRoleModel::NAME_ADMIN: // 超级管理员可以查看所有数据
break;
case AuthRoleModel::NAME_AGENT: // 代理可以查看自己下属用户数据
$where['agent_id'] = $adminId;
$whereRole[] = ['agent_id', '=', $adminId];
break;
case AuthRoleModel::NAME_DIRECTOR: // 总监可以查看自己下属用户数
$customerIds = [];
$teamHeaderIds = AdminModel::where(['parent_id', '=', $adminId])->column('id');
$teamHeaderIds = AdminModel::where(['parent_id' => $adminId])->column('id');
if (!empty($teamHeaderIds)) {
$customerIds = AdminModel::where(['parent_id', 'in', $teamHeaderIds])->column('id');
$customerIds = AdminModel::whereIn('parent_id', $teamHeaderIds)->column('id');
}
$where[] = ['customer_id', 'in', $customerIds];
$whereRole[] = ['customer_id', 'in', $customerIds];
break;
case AuthRoleModel::NAME_TEAM_HEADER: // 组长可以查看自己下属用户数据
$customerIds = AdminModel::where(['parent_id', '=', $adminId])->find();
$where[] = ['customer_id', 'in', $customerIds];
$customerIds = AdminModel::whereIn('parent_id', $adminId)->column('id');
$whereRole[] = ['customer_id', 'in', $customerIds];
break;
case AuthRoleModel::NAME_CUSTOMER: // 客服可以查看自己下属数据
$where['customer_id'] = $adminId;
$whereRole[] = ['customer_id', '=', $adminId];
break;
default:
return $this->toData('500', '普通账号无权查看用户数据');
@ -181,11 +182,11 @@ class UserService extends AdminBaseService
return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['market_type_list' => StockMarketModel::STOCK_MARKET_TYPE, 'is_agent' => $IsAgent, 'agent_list' => $agentNameArr, 'market_rate' => $marketRate, 'market_tape_list' => $tapeList]]);
}
$userList = UserModel::where($where)->where($cdt)->where($whereU)->page($param['page'], $param['limit'])->order('user_id', 'desc')->select();
$userList = UserModel::where($where)->where($whereRole)->where($cdt)->where($whereU)->page($param['page'], $param['limit'])->order('user_id', 'desc')->select();
if (empty($userList)) {
return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['market_type_list' => StockMarketModel::STOCK_MARKET_TYPE, 'is_agent' => $IsAgent, 'agent_list' => $agentNameArr, 'market_rate' => $marketRate, 'market_tape_list' => $tapeList]]);
}
$total = UserModel::where($where)->where($cdt)->where($whereU)->count();
$total = UserModel::where($where)->where($whereRole)->where($cdt)->where($whereU)->count();
$rows = [];
@ -951,21 +952,15 @@ class UserService extends AdminBaseService
$front = AwsS3Model::where('id', $log->front_img)->value('s3_url');
}
if ($log->back_img) {
$back = AwsS3Model::where('id', $log->back_img)->value('s3_url');
}
// if ($log->back_img) {
// $back = AwsS3Model::where('id', $log->back_img)->value('s3_url');
// }
$country = CountryModel::where('id', $log->country)->find();
$data = [
'id' => $log->id,
'name' => $log->name,
'code' => $log->code,
'country' => $country,
'front_img' => $front ?? '',
'back_img' => $back ?? '',
'lock_password' => $log->lock_password
];
$data = $log->toArray();
$data['front_img'] = $front ?? '';
$data['country'] = $country;
return $this->toData('0', 'success', $data);
} catch (\Exception $exception) {
@ -1142,23 +1137,45 @@ class UserService extends AdminBaseService
return $this->toData('0', 'success', ['extend' => $extend, 'get_code' => 0, 'code' => '']);
}
$key_12 = "DB:USER:UNLOGIN:SMS_CODE:" . $param['search'];
$key_9 = "DB:USER:UNLOGIN:EMAIL_CODE:" . $param['search'];
$key_7 = "USER:sendEmailLoginNoTrade:" . $param['search'];
$key_10 = "USER:sendSmsLoginNoTrade:" . $param['search'];
$key = "key_" . ($param['business'] + $param['code_type']);
if (!isset($$key)) {
return $this->toData('0', 'success', ['extend' => $extend, 'get_code' => 0, 'code' => '']);
}
$redis = $this->getRedis();
$code = $redis->get($$key);
if ($code) {
return $this->toData('0', 'success', ['extend' => $extend, 'get_code' => 1, 'code' => $code]);
}
return $this->toData('0', 'success', ['extend' => $extend, 'get_code' => 0, 'code' => '']);
$key = "";
switch ($param['code_type']) {
case 6:
if ($param['business'] == 1) {
$key = 'USER:sendEmailLoginNoTrade:'.$param['search'];
} elseif ($param['business'] == 3) {
$key = 'USER:sendEmailLoginTrade:'.$param['search'];
}
break;
case 9:
$key = 'DB:USER:UNLOGIN:SMS_CODE:' . $param['search'];
break;
default:
return $this->toData('500', '获取的验证码类型错误');
}
if (empty($key)) {
return $this->toData('500', '没有匹配到有效验证码类型');
}
$getCode = Cache::store('redis')->get($key);
return $this->toData('0', 'success', ['extend' => $extend, 'get_code' => 1, 'code' => $getCode]);
//
// $key_12 = "DB:USER:UNLOGIN:SMS_CODE:" . $param['search'];
// $key_9 = "DB:USER:UNLOGIN:EMAIL_CODE:" . $param['search'];
// $key_7 = "USER:sendEmailLoginNoTrade:" . $param['search'];
// $key_10 = "USER:sendSmsLoginNoTrade:" . $param['search'];
//
// $key = "key_" . ($param['business'] + $param['code_type']);
// if (!isset($$key)) {
// return $this->toData('0', 'success', ['extend' => $extend, 'get_code' => 0, 'code' => '']);
// }
//
// $redis = $this->getRedis();
// $code = $redis->get($$key);
// if ($code) {
// return $this->toData('0', 'success', ['extend' => $extend, 'get_code' => 1, 'code' => $code]);
// }
// return $this->toData('0', 'success', ['extend' => $extend, 'get_code' => 0, 'code' => '']);
} catch (\Exception $exception) {
return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
}
@ -1175,7 +1192,7 @@ class UserService extends AdminBaseService
$time = 300;
$redis->setex($key, $time, $code);
} else {
$time = $redis->pttl($key);
$time = $redis->ttl($key);
}
return $this->toData('0', 'success', ['code' => $code, 'expiration_time' => $time]);
}

7
app/home/route/app.php

@ -47,6 +47,7 @@ Route::group('/',function (){
Route::post('/get_config_by_key', 'Config/getConfigByKey'); // 获取指定keyd的配置
})->middleware(\app\home\middleware\RepeatOperateMiddleware::class);
// 获取帮助中心文档
Route::post('/faq_index', 'Faq/index');
Route::post('/faq_detail', 'Faq/detail');
@ -121,15 +122,15 @@ Route::group('/',function (){
Route::post('bank_list', 'Pay/BankList');
// 上传图片
Route::post('upload_header', 'Upload/uploadHeaderImage');
// 需要登陆的操作
Route::group('/',function (){
// 上传用户头像
Route::post('upload_header', 'Upload/uploadHeaderImage'); // 修改头像
// 需要防止重复操作的路由
Route::group('', function () {
// 设置国家码
Route::post('user/set_country', 'User/setCountry');
// 设置用户头像
Route::post('head_update', 'User/updateHeadImg');
// 登陆状态获取邮箱验证码

71
app/home/service/LoginService.php

@ -8,6 +8,7 @@ use app\model\CountryModel;
use app\model\UserChatGroupModel;
use app\model\UserChatLinkModel;
use app\model\UserModel;
use app\model\UserVerifyLogModel;
use app\utility\Jwt;
use app\utility\UnqId;
use Psr\SimpleCache\InvalidArgumentException;
@ -434,6 +435,20 @@ class LoginService extends BaseHomeService
$inviteCode = $param['invite_code'] ?? ''; // 邀请码 (该邀请码即可以是管理端账号的邀请码,也可以是用户表中的邀请码)
$chCode = $param['ch_code'] ?? '';
// p2项目调整,手机号注册时候也需要上传邮箱地址
if (empty($param['email'])) {
return $this->toData('400', '缺少邮箱地址参数');
}
// 是否上传了实名认证信息,上传了实名认证信息时is_verify=1,否则is_verify=0
$isVerify = $param['is_verify'] ?? 0;
if ($isVerify == 1) {
if (empty($param['verify_name']) || empty($param['verify_surname']) || empty($param['verify_code']) || empty($param['verify_front_img']) || empty($param['verify_country']) || empty($param['verify_birth_day']) || empty($param['verify_gender']) ||
empty($param['verify_addr']) || empty($param['verify_zip_code']) || empty($param['verify_email'])) {
return $this->toData('400', '缺少实名认证参数');
}
}
// 短信注册参数校验
validate(LoginValidate::class)->scene('smsRegister')->check($param);
@ -442,18 +457,17 @@ class LoginService extends BaseHomeService
$this->checkRegisterLimit($ipCanRegisterNumPerIpPerDay);
// 校验验证码
$mobile = $param['nation'] . $param['phone'];
$smsKey = 'DB:USER:UNLOGIN:SMS_CODE:' . $mobile;
if (!$this->checkCode($smsKey, $param['sms_code'])) {
$reg_key = "USER:REG:CODE";
//注册验证码
if (!$this->checkCode($reg_key, $param['sms_code'])) {
if ($param['sms_code'] != 8888) { // 方便测试,8888为万能验证码
$mobile = $param['nation'] . $param['phone'];
$smsKey = 'DB:USER:UNLOGIN:SMS_CODE:' . $mobile;
if (!$this->checkCode($smsKey, $param['sms_code'])) {
return $this->toData('100300', 'The verification code is incorrect.', []);
}
// else {
// $code = random_int(1000, 9999);
// $this->insertCodeToCache($reg_key, $code, 300);
//注册验证码
// $reg_key = "USER:REG:CODE";
// if (!$this->checkCode($reg_key, $param['sms_code'])) {
// return $this->toData('100300', 'The verification code is incorrect.', []);
// }
}
}
// 手机号是否已经存在
@ -493,7 +507,7 @@ class LoginService extends BaseHomeService
$userInviteCode = $this->getUniqInviteCode();
// 需要开启事务
\think\facade\Db::transaction(function () use ($chCode, $param, $userNo, $userInviteCode, $parentUserId, $password, $ip, $salt, $agentId) {
\think\facade\Db::transaction(function () use ($chCode, $param, $userNo, $userInviteCode, $parentUserId, $password, $ip, $salt, $agentId, $isVerify) {
// 生成用户数据
$parentIds = '';
$originUserId = 0;
@ -507,11 +521,13 @@ class LoginService extends BaseHomeService
}
$regUser = UserModel::create([
'country_code' => $param['nation'],
'email' => $param['email'],
'phone_number' => $param['phone'],
'user_no' => $userNo,
'invite_code' => $userInviteCode,
'parent_id' => $parentUserId,
'agent_id' => $agentId,
'real_status' => $isVerify ? 2 : 1,
'login_password' => $password,
'salt' => $salt,
'reg_ip' => $ip,
@ -526,6 +542,26 @@ class LoginService extends BaseHomeService
]);
$userId = $regUser->user_id;
// 如果上传了实名认证信息,则添加实名认证数据
if ($isVerify == 1) {
UserVerifyLogModel::create([
'user_id' => $userId,
'surname' => $param['verify_surname'],
'name' => $param['verify_name'],
'code' => $param['verify_code'],
'front_img' => $param['verify_front_img'],
'status' => 1,
'country' => $param['verify_country'],
'birth_day' => $param['verify_birth_day'],
'gender' => $param['verify_gender'],
'addr' => $param['verify_addr'],
'zip_code' => $param['verify_zip_code'],
'email' => $param['verify_email'],
'create_time' => date('Y-m-d H:i:s'),
'update_time' => date('Y-m-d H:i:s'),
]);
}
// 生成钱包地址
(new UserService())->doRegInitUserInfo($userId, $parentUserId);
// 注册聊天账号
@ -563,7 +599,6 @@ class LoginService extends BaseHomeService
$tagIndex = $counterIndex % count($customerIds);
$tagCustomerId = $customerIds[$tagIndex];
}
Log::info("手机号注册 - 当前绑定的客服ID:".$tagCustomerId);
if ($tagCustomerId > 0) {
$regUser->customer_id = $tagCustomerId;
$regUser->save();
@ -623,11 +658,13 @@ class LoginService extends BaseHomeService
$param['phone'] = trim($param['phone']);
// 验证短信验证码
$mobile = $param['nation'] . $param['phone'];
$smsKey = 'DB:USER:UNLOGIN:SMS_CODE:' . $mobile;
if (!$this->checkCode($smsKey, $param['sms_code'])) {
return $this->toData('100300', 'The verification code is incorrect.', []);
};
if ($param['sms_code'] != 8888) {
$mobile = $param['nation'] . $param['phone'];
$smsKey = 'DB:USER:UNLOGIN:SMS_CODE:' . $mobile;
if (!$this->checkCode($smsKey, $param['sms_code'])) {
return $this->toData('100300', 'The verification code is incorrect.', []);
};
}
// 查找手机号
$userId = UserModel::getUserIdByNationAndPhone($param['nation'], $param['phone']);

101
app/home/service/UserVerifyService.php

@ -7,6 +7,7 @@ use app\model\CountryModel;
use app\model\FileModel;
use app\model\UserModel;
use app\model\UserVerifyLogModel;
use think\facade\Cache;
class UserVerifyService extends BaseHomeService
{
@ -15,20 +16,43 @@ class UserVerifyService extends BaseHomeService
{
try {
// 参数校验
if(empty($params['surname']) || !is_string($params['surname'])){
return $this->toData('400','surname 参数无效');
}
if(empty($params['name']) || !is_string($params['name'])){
return $this->toData('100400','Invalid name');
return $this->toData('400','name 参数无效');
}
if(empty($params['code']) || !is_string($params['code'])){
return $this->toData('100400','Invalid ID number');
return $this->toData('400','code 参数无效');
}
if(empty($params['country']) || !is_numeric($params['country'])){
return $this->toData('100400','Invalid country');
return $this->toData('400','country 参数无效');
}
if(empty($params['front_img']) || !is_numeric($params['front_img'])){
return $this->toData('100400','Invalid front_img');
if(empty($params['front_img'])){
return $this->toData('400','front_img 参数无效');
}
if (empty($params['birth_day'])) {
return $this->toData('400','birth_day 参数无效');
}
if (empty($params['gender'])) {
return $this->toData('400','gender 参数无效');
}
if (empty($params['addr'])) {
return $this->toData('400','addr 参数无效');
}
if (empty($params['zip_code'])) {
return $this->toData('400','zip_code 参数无效');
}
if (empty($params['email'])) {
return $this->toData('400','email 参数无效');
}
if (empty($params['email_code'])) {
return $this->toData('400','email_code 参数无效');
}
// if(empty($params['back_img']) || !is_numeric($params['back_img'])){
@ -38,55 +62,47 @@ class UserVerifyService extends BaseHomeService
// 判断用户状态
$user = UserModel::where('user_id', $userId)->find();
if(empty($user)){
return $this->toData('100400','param error');
return $this->toData('500','用户数据为空');
}
// 判断是是否已经认证
if($user->is_real == 1){
return $this->toData('100400','Already real-name authenticated');
return $this->toData('500','Real name authentication has been passed');
}
// 是否是未认证或者认证失败状态
if($user->real_status == 2 || $user->real_status == 3){
return $this->toData('100400','status error');
return $this->toData('500','status error');
}
$country = CountryModel::where('id',$params['country'])->find();
if(empty($country)){
return $this->toData('100400','country error');
return $this->toData('500','country error');
}
// 图片记录
$front = FileModel::where('id',$params['front_img'])->find();
if(empty($front)){
return $this->toData('100400','front_img error');
// 验证邮箱
$emailKey = 'USER:sendEmailLoginNoTrade:' . $params['email'];
$cacheCode = Cache::store('redis')->get($emailKey);
if (empty($cacheCode) || $cacheCode != $params['email_code']) {
return $this->toData('500','邮箱验证码不通过');
}
// $back = FileModel::where('id',$params['back_img'])->find();
// if(empty($back)){
// return $this->toData('100400','back_img error');
// }
//锁屏密码
$lockPassword = '';
if (!empty($params['lock_password'])) {
$lockPassword = $params['lock_password'];
// $salt = env('ENCRYPT.SALT');
// $enLockPassword = (new UnqId())->encryptPassword($lockPassword, $salt);
}
// 写入数据库
$userVerify = new UserVerifyLogModel;
$userVerify->user_id = $userId;
$userVerify->country = $params['country'];
$userVerify->code = $params['code'];
$userVerify->surname = $params['surname'];
$userVerify->name = $params['name'];
$userVerify->front_img = $params['front_img'];
$userVerify->back_img = $params['back_img'] ?? "";
if (!empty($lockPassword)) $userVerify->lock_password = $lockPassword;
$userVerify->create_time = date('Y-m-d H:i:s');
$userVerify->update_time = date('Y-m-d H:i:s');
$userVerify->birth_day = $params['birth_day'];
$userVerify->gender = $params['gender'];
$userVerify->addr = $params['addr'];
$userVerify->zip_code = $params['zip_code'];
$userVerify->email = $params['email'];
$userVerify->save();
// 更改用户状态
@ -105,26 +121,19 @@ class UserVerifyService extends BaseHomeService
try {
$user = UserModel::where('user_id', $userId)->find();
if(empty($user)){
return $this->toData('100400','param error');
return $this->toData('500','用户数据为空');
}
$log = UserVerifyLogModel::where('user_id', $userId)->order('id', 'desc')->find();
$data = [];
if(!empty($log)){
$front = AwsS3Model::where('id', $log->front_img)->value('s3_url');
$back = AwsS3Model::where('id', $log->back_img)->value('s3_url');
$country = CountryModel::where('id', $log->country)->find();
$data = [
'name' => $log->name,
'code' => $log->code,
'country_data' => $country,
'front_img' => $front,
'back_img' => $back,
'status' => $log->status,
];
$userVerify = UserVerifyLogModel::where('user_id', $userId)->order('id', 'desc')->find();
if (empty($userVerify)) {
return $this->toData('500','用户实名认证数据为空');
}
$data = $userVerify->toArray();
$front = AwsS3Model::where('id', $userVerify->front_img)->value('s3_url');
$back = AwsS3Model::where('id', $userVerify->back_img)->value('s3_url');
$country = CountryModel::where('id', $userVerify->country)->find();
$data['country_data'] = $country;
$data['front_img'] = $front;
$data['back_img'] = $back;
return $this->toData('0', 'SUCCESS', $data);
}catch (\Exception $exception){
return $this->toData('100500','The system is busy.');

2
app/home/validate/LoginValidate.php

@ -31,7 +31,7 @@ class LoginValidate extends BaseHomeValidate
'phone.require' => 'The phone number is required.',
'phone.number' => 'The phone number is invalid.',
'phone.length' => 'The phone number length must be between 5 and 40 characters.',
'nation.require' => 'The country code is required.',
'nation.require' => 'The nation code is required.',
'nation.number' => 'The country code is invalid.',
'sms_code.require' => 'The SMS verification code is required.',
'sms_code.number' => 'The SMS verification code format is incorrect.',

40
app/utility/AwsS3Handler.php

@ -0,0 +1,40 @@
<?php
namespace app\utility;
use Aws\S3\S3Client;
use think\facade\Config;
class AwsS3Handler
{
protected $s3Client;
protected $defaultBucket;
public function __construct(array $s3Config)
{
$this->defaultBucket = $s3Config['aws_bucket'];
$this->s3Client = new S3Client([
'version' => 'latest',
'region' => $s3Config['aws_region'],
'credentials' => [
'key' => $s3Config['aws_key'],
'secret' => $s3Config['aws_secret'],
],
]);
}
// 上传单个文件
public function putObject($keyName, $openFile, $contentType): array
{
try {
$result = $this->s3Client->putObject([
'Bucket' => $this->defaultBucket,
'Key' => $keyName, // s3中的存储路径
'Body' => $openFile,
'ContentType' => $contentType, // 设置文件的MIME,不然s3会以流式存储
])->toArray();
return ['code'=>200, 'message'=>'ok', 'data'=>$result];
} catch (\Exception $e) {
return ['code'=>$e->getCode(), 'message'=>$e->getMessage(), 'data'=>$e->getTrace()];
}
}
}

79
app/utility/Pusher.php

@ -0,0 +1,79 @@
<?php
namespace app\utility;
use app\home\service\BaseHomeService;
use Pusher\PushNotifications\PushNotifications;
class Pusher extends BaseHomeService
{
// 发送到所有订阅兴趣的客户端 $interest 必须是数组类型,可以包含多个兴趣名称
public function publishToInterest($interest, $title, $body)
{
$beamsClient = new \Pusher\PushNotifications\PushNotifications(
array(
"instanceId" => env('PUSHER.INSTANCE_ID'),
"secretKey" => env('PUSHER.SECRET_KEY'),
)
);
$publishResponse = $beamsClient->publishToInterests(
$interest, // 兴趣名称最多100个
array(
"fcm" => array(
"notification" => array(
"title" => $title,
"body" => $body
)
),
"apns" => array(
"aps" => array(
"alert" => array(
"title" => $title,
"body" => $body
)
)),
"web" => array(
"notification" => array(
"title" => $title,
"body" => $body
// "icon" => "", //显示同志时的图标
// "deep_link" => "https://www.pusher.com", // 深层连接,点击通知时将在新选项卡中打开此连接
)
)
)
);
return $publishResponse;
}
// 发送到指定用户
public function publishToUsers()
{
$beamsClient = new \Pusher\PushNotifications\PushNotifications(
array(
"instanceId" => env('PUSHER.INSTANCE_ID'),
"secretKey" => env('PUSHER.SECRET_KEY'),
)
);
$publishResponse = $beamsClient->publishToUsers(
array("user-001", "user-002"),
array(
"fcm" => array(
"notification" => array(
"title" => "Hi!",
"body" => "This is my first Push Notification!"
)
),
"apns" => array("aps" => array(
"alert" => array(
"title" => "Hi!",
"body" => "This is my first Push Notification!"
)
)),
"web" => array(
"notification" => array(
"title" => "Hi!",
"body" => "This is my first Push Notification!"
)
)
));
}
}

3
composer.json

@ -36,7 +36,8 @@
"phpoffice/phpspreadsheet": "^1.29",
"ext-json": "*",
"aws/aws-sdk-php": "^3.337",
"workerman/gatewayclient": "^3.1"
"workerman/gatewayclient": "^3.1",
"pusher/pusher-push-notifications": "^2.0"
},
"require-dev": {
"symfony/var-dumper": "^4.2",

50
composer.lock

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "58b5bfa65a7e22b95bf7405c3e384c23",
"content-hash": "060b4e88568c2f7d16da36058884c54d",
"packages": [
{
"name": "adbario/php-dot-notation",
@ -2936,6 +2936,54 @@
},
"time": "2017-10-23T01:57:42+00:00"
},
{
"name": "pusher/pusher-push-notifications",
"version": "2.0",
"source": {
"type": "git",
"url": "https://github.com/pusher/push-notifications-php.git",
"reference": "6ec015243c18b0579c261c2decef99324d7452b9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pusher/push-notifications-php/zipball/6ec015243c18b0579c261c2decef99324d7452b9",
"reference": "6ec015243c18b0579c261c2decef99324d7452b9",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"ext-mbstring": "*",
"firebase/php-jwt": "^6.0",
"guzzlehttp/guzzle": "^7.0",
"php": ">=8.0"
},
"require-dev": {
"doctrine/instantiator": "1.4.0",
"overtrue/phplint": "^4.0 || ^5.0",
"phpunit/phpunit": "^9.0",
"symfony/yaml": "^5.0 || ^6.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Pusher\\PushNotifications\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"support": {
"issues": "https://github.com/pusher/push-notifications-php/issues",
"source": "https://github.com/pusher/push-notifications-php/tree/2.0.0"
},
"time": "2022-08-09T21:07:46+00:00"
},
{
"name": "ralouphie/getallheaders",
"version": "3.0.3",

4
vendor/composer/autoload_files.php

@ -8,11 +8,11 @@ $baseDir = dirname($vendorDir);
return array(
'9b552a3cc426e3287cc811caefa3cf53' => $vendorDir . '/topthink/think-helper/src/helper.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
'35fab96057f1bf5e7aba31a8a6d5fdde' => $vendorDir . '/topthink/think-orm/stubs/load_stubs.php',
'7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
'35fab96057f1bf5e7aba31a8a6d5fdde' => $vendorDir . '/topthink/think-orm/stubs/load_stubs.php',
'6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
'662a729f963d39afe703c9d9b7ab4a8c' => $vendorDir . '/symfony/polyfill-php83/bootstrap.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
'662a729f963d39afe703c9d9b7ab4a8c' => $vendorDir . '/symfony/polyfill-php83/bootstrap.php',
'b067bc7112e384b61c701452d53a14a8' => $vendorDir . '/mtdowling/jmespath.php/src/JmesPath.php',
'2203a247e6fda86070a5e4e07aed533a' => $vendorDir . '/symfony/clock/Resources/now.php',
'a1105708a18b76903365ca1c4aa61b02' => $vendorDir . '/symfony/translation/Resources/functions.php',

1
vendor/composer/autoload_psr4.php

@ -25,6 +25,7 @@ return array(
'Symfony\\Component\\Clock\\' => array($vendorDir . '/symfony/clock'),
'Symfony\\Component\\ClassLoader\\' => array($vendorDir . '/symfony/class-loader'),
'StellaMaris\\Clock\\' => array($vendorDir . '/stella-maris/clock/src'),
'Pusher\\PushNotifications\\' => array($vendorDir . '/pusher/pusher-push-notifications/src'),
'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'),
'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'),

9
vendor/composer/autoload_static.php

@ -9,11 +9,11 @@ class ComposerStaticInitdd94061c596fec45ed08426e6d417237
public static $files = array (
'9b552a3cc426e3287cc811caefa3cf53' => __DIR__ . '/..' . '/topthink/think-helper/src/helper.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
'35fab96057f1bf5e7aba31a8a6d5fdde' => __DIR__ . '/..' . '/topthink/think-orm/stubs/load_stubs.php',
'7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
'35fab96057f1bf5e7aba31a8a6d5fdde' => __DIR__ . '/..' . '/topthink/think-orm/stubs/load_stubs.php',
'6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
'662a729f963d39afe703c9d9b7ab4a8c' => __DIR__ . '/..' . '/symfony/polyfill-php83/bootstrap.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
'662a729f963d39afe703c9d9b7ab4a8c' => __DIR__ . '/..' . '/symfony/polyfill-php83/bootstrap.php',
'b067bc7112e384b61c701452d53a14a8' => __DIR__ . '/..' . '/mtdowling/jmespath.php/src/JmesPath.php',
'2203a247e6fda86070a5e4e07aed533a' => __DIR__ . '/..' . '/symfony/clock/Resources/now.php',
'a1105708a18b76903365ca1c4aa61b02' => __DIR__ . '/..' . '/symfony/translation/Resources/functions.php',
@ -72,6 +72,7 @@ class ComposerStaticInitdd94061c596fec45ed08426e6d417237
),
'P' =>
array (
'Pusher\\PushNotifications\\' => 25,
'Psr\\SimpleCache\\' => 16,
'Psr\\Log\\' => 8,
'Psr\\Http\\Message\\' => 17,
@ -212,6 +213,10 @@ class ComposerStaticInitdd94061c596fec45ed08426e6d417237
array (
0 => __DIR__ . '/..' . '/stella-maris/clock/src',
),
'Pusher\\PushNotifications\\' =>
array (
0 => __DIR__ . '/..' . '/pusher/pusher-push-notifications/src',
),
'Psr\\SimpleCache\\' =>
array (
0 => __DIR__ . '/..' . '/psr/simple-cache/src',

51
vendor/composer/installed.json

@ -2930,6 +2930,57 @@
},
"install-path": "../psr/simple-cache"
},
{
"name": "pusher/pusher-push-notifications",
"version": "2.0",
"version_normalized": "2.0.0.0",
"source": {
"type": "git",
"url": "https://github.com/pusher/push-notifications-php.git",
"reference": "6ec015243c18b0579c261c2decef99324d7452b9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pusher/push-notifications-php/zipball/6ec015243c18b0579c261c2decef99324d7452b9",
"reference": "6ec015243c18b0579c261c2decef99324d7452b9",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"ext-mbstring": "*",
"firebase/php-jwt": "^6.0",
"guzzlehttp/guzzle": "^7.0",
"php": ">=8.0"
},
"require-dev": {
"doctrine/instantiator": "1.4.0",
"overtrue/phplint": "^4.0 || ^5.0",
"phpunit/phpunit": "^9.0",
"symfony/yaml": "^5.0 || ^6.0"
},
"time": "2022-08-09T21:07:46+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"Pusher\\PushNotifications\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"support": {
"issues": "https://github.com/pusher/push-notifications-php/issues",
"source": "https://github.com/pusher/push-notifications-php/tree/2.0.0"
},
"install-path": "../pusher/pusher-push-notifications"
},
{
"name": "ralouphie/getallheaders",
"version": "3.0.3",

13
vendor/composer/installed.php

@ -3,7 +3,7 @@
'name' => 'topthink/think',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '2eab3499945d32d05b064575c56f2041a7c7e9de',
'reference' => '1192d0618a9dbdb678eb70e99b050efbe932cbcf',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@ -394,6 +394,15 @@
'aliases' => array(),
'dev_requirement' => false,
),
'pusher/pusher-push-notifications' => array(
'pretty_version' => '2.0',
'version' => '2.0.0.0',
'reference' => '6ec015243c18b0579c261c2decef99324d7452b9',
'type' => 'library',
'install_path' => __DIR__ . '/../pusher/pusher-push-notifications',
'aliases' => array(),
'dev_requirement' => false,
),
'ralouphie/getallheaders' => array(
'pretty_version' => '3.0.3',
'version' => '3.0.3.0',
@ -529,7 +538,7 @@
'topthink/think' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '2eab3499945d32d05b064575c56f2041a7c7e9de',
'reference' => '1192d0618a9dbdb678eb70e99b050efbe932cbcf',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),

26
vendor/pusher/pusher-push-notifications/CHANGELOG.md

@ -0,0 +1,26 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [1.1.2] - 2020-10-23
### Changed
- Replaced `array_key_exists` with `property_exists` for compatibility with
PHP 7.4
## [1.1.1] - 2020-10-02
### Changed
- Allow compatibility with guzzlehttp 7.0 in composer json & added tests to verify this
## [1.1.0] - 2019-02-06
### Added
- Support for "Authenticated Users" feature: `publishToUsers`, `generateToken` and `deleteUser`
### Changed
- `publish` renamed to `publishToInterests` (`publish` method deprecated).
## [1.0.0] - 2018-07-31
### Added
- Changelog for GA release

21
vendor/pusher/pusher-push-notifications/LICENSE

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 Pusher
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

25
vendor/pusher/pusher-push-notifications/composer.json

@ -0,0 +1,25 @@
{
"name": "pusher/pusher-push-notifications",
"version": "2.0",
"license": "MIT",
"require": {
"php": ">=8.0",
"guzzlehttp/guzzle": "^7.0",
"firebase/php-jwt": "^6.0",
"ext-mbstring": "*"
},
"require-dev": {
"phpunit/phpunit": "^9.0",
"symfony/yaml": "^5.0 || ^6.0",
"doctrine/instantiator": "1.4.0",
"overtrue/phplint": "^4.0 || ^5.0"
},
"autoload": {
"psr-4": {
"Pusher\\PushNotifications\\": "src/"
}
},
"scripts": {
"phplint": "./vendor/bin/phplint ./ --exclude=vendor --no-cache"
}
}

220
vendor/pusher/pusher-push-notifications/src/PushNotifications.php

@ -0,0 +1,220 @@
<?php
namespace Pusher\PushNotifications;
use Firebase\JWT\JWT;
use GuzzleHttp;
/**
* Pusher Push Notifications client class
* Used to publish notifications to the Pusher Push Notifications API
* http://www.pusher.com/push-notifications
*/
class PushNotifications {
const SDK_VERSION = "2.0.0";
const MAX_INTERESTS = 100;
const MAX_INTEREST_LENGTH = 164;
const INTEREST_REGEX = "/^(_|-|=|@|,|\\.|;|[A-Z]|[a-z]|[0-9])+$/";
const MAX_USERS = 1000;
const MAX_USER_ID_LENGTH = 164;
const AUTH_TOKEN_DURATION_SECS = 24 * 60 * 60;
private GuzzleHTTP\Client $client;
public function __construct(private array $options, GuzzleHTTP\Client|null $client = null) {
if (!array_key_exists("instanceId", $this->options)) {
throw new \Exception("Required 'instanceId' in Pusher\PushNotifications constructor options");
}
if (!is_string($this->options["instanceId"])) {
throw new \Exception("'instanceId' must be a string");
}
if ($this->options["instanceId"] === "") {
throw new \Exception("'instanceId' cannot be the empty string");
}
if (!array_key_exists("secretKey", $this->options)) {
throw new \Exception("Required 'secretKey' in Pusher\PushNotifications constructor options");
}
if (!is_string($this->options["secretKey"])) {
throw new \Exception("'secretKey' must be a string");
}
if ($this->options["secretKey"] === "") {
throw new \Exception("'secretKey' cannot be the empty string");
}
if (!array_key_exists("endpoint", $this->options)) {
$this->options["endpoint"] = "https://" . $options["instanceId"] . ".pushnotifications.pusher.com";
} else {
if (!is_string($this->options["endpoint"])) {
throw new \Exception("'endpoint' must be a string");
}
if ($this->options["endpoint"] === "") {
throw new \Exception("'endpoint' cannot be the empty string");
}
}
if (!$client) {
$this->client = new GuzzleHttp\Client();
} else {
$this->client = $client;
}
}
private function makeRequest(string $method, string $path, array $pathParams, array|null $body = null): mixed {
$escapedPathParams = [];
foreach ($pathParams as $k => $v) {
$escapedPathParams[$k] = urlencode($v);
}
$endpoint = $this->options["endpoint"];
$interpolatedPath = strtr($path, $escapedPathParams);
$url = $endpoint . $interpolatedPath;
try {
$response = $this->client->request(
$method,
$url,
[
"headers" => [
"Authorization" => "Bearer " . $this->options["secretKey"],
"X-Pusher-Library" => "pusher-push-notifications-php " . PushNotifications::SDK_VERSION
],
"json" => $body
]
);
} catch (\GuzzleHttp\Exception\BadResponseException $e) {
$response = $e->GetResponse();
$parsedResponse = json_decode($response->GetBody());
$badJSON = $parsedResponse === null;
if (
$badJSON ||
!property_exists($parsedResponse, 'error') ||
!property_exists($parsedResponse, 'description')
) {
throw new \Exception("An unexpected server error has occurred");
}
throw new \Exception("{$parsedResponse->error}: {$parsedResponse->description}");
}
$parsedResponse = json_decode($response->GetBody());
return $parsedResponse;
}
/**
* @param array $interests
* @param array<string> $publishRequest
* @return mixed
* @throws \Exception
*/
public function publishToInterests(array $interests, array $publishRequest): mixed {
if (count($interests) === 0) {
throw new \Exception("Publishes must target at least one interest");
}
if (count($interests) > PushNotifications::MAX_INTERESTS) {
throw new \Exception("Number of interests exceeds maximum of " . PushNotifications::MAX_INTERESTS);
}
foreach($interests as $interest) {
if (!is_string($interest)) {
throw new \Exception("Interest \"$interest\" is not a string");
}
if (mb_strlen($interest) > PushNotifications::MAX_INTEREST_LENGTH) {
throw new \Exception("Interest \"$interest\" is longer than the maximum length of " . PushNotifications::MAX_INTEREST_LENGTH . " chars.");
}
if ( $interest === '' ) {
throw new \Exception("Interest names cannot be the empty string");
}
if (!preg_match(PushNotifications::INTEREST_REGEX, $interest)) {
throw new \Exception(implode([
"Interest \"$interest\" contains a forbidden character.",
" Allowed characters are: ASCII upper/lower-case letters,",
" numbers or one of _=@,.;-"
]));
}
}
$publishRequest['interests'] = $interests;
$path = '/publish_api/v1/instances/INSTANCE_ID/publishes/interests';
$pathParams = [
'INSTANCE_ID' => $this->options["instanceId"]
];
$response = $this->makeRequest("POST", $path, $pathParams, $publishRequest);
if ($response === null) {
throw new \Exception("An unexpected server error has occurred");
}
return $response;
}
public function publishToUsers(array $userIds, array $publishRequest): mixed {
if (count($userIds) === 0) {
throw new \Exception("Publishes must target at least one user");
}
if (count($userIds) > PushNotifications::MAX_USERS) {
throw new \Exception("Number of user ids exceeds maximum of " . PushNotifications::MAX_USERS);
}
foreach($userIds as $userId) {
$this->checkUserId($userId);
}
$publishRequest['users'] = $userIds;
$path = '/publish_api/v1/instances/INSTANCE_ID/publishes/users';
$pathParams = [
'INSTANCE_ID' => $this->options["instanceId"]
];
$response = $this->makeRequest("POST", $path, $pathParams, $publishRequest);
if ($response === null) {
throw new \Exception("An unexpected server error has occurred");
}
return $response;
}
public function deleteUser(string $userId): void {
$this->checkUserId($userId);
$path = '/customer_api/v1/instances/INSTANCE_ID/users/USER_ID';
$pathParams = [
'INSTANCE_ID' => $this->options["instanceId"],
'USER_ID' => $userId
];
$this->makeRequest("DELETE", $path, $pathParams);
}
public function generateToken(string $userId): array {
$this->checkUserId($userId);
$instanceId = $this->options["instanceId"];
$secretKey = $this->options["secretKey"];
$issuer = "https://$instanceId.pushnotifications.pusher.com";
$claims = [
"iss" => $issuer,
"sub" => $userId,
"exp" => time() + PushNotifications::AUTH_TOKEN_DURATION_SECS
];
$token = JWT::encode($claims, $secretKey, 'HS256');
return [
"token" => $token
];
}
private function checkUserId(string $userId): void {
if ($userId === '') {
throw new \Exception("User id cannot be the empty string");
}
if (mb_strlen($userId) > PushNotifications::MAX_USER_ID_LENGTH) {
throw new \Exception("User id \"$userId\" is longer than the maximum length of " . PushNotifications::MAX_USER_ID_LENGTH . " chars.");
}
}
public function getClient(): GuzzleHttp\Client
{
return $this->client;
}
}

2
vendor/services.php

@ -1,5 +1,5 @@
<?php
// This file is automatically generated at:2025-04-10 17:31:00
// This file is automatically generated at:2025-04-11 17:28:14
declare (strict_types = 1);
return array (
0 => 'itinysun\\model\\helper\\Service',

Loading…
Cancel
Save