From 83cfce0d7ac819592b8af0aec63f1034641638e5 Mon Sep 17 00:00:00 2001 From: chuan <2154243450@qq.com> Date: Fri, 9 May 2025 14:01:55 +0800 Subject: [PATCH] up --- app/admin/controller/Config.php | 100 ++++++++++++++++++++---- app/admin/controller/Notice.php | 27 ++++++- app/admin/route/app.php | 2 +- app/home/service/WalletService.php | 10 ++- app/model/UserGoldFuturesLogModel.php | 21 +++++ app/model/UserStockIndexInrLogModel.php | 21 +++++ app/utility/MongoConnection.php | 13 ++- app/utility/Pusher.php | 38 +++++---- 8 files changed, 199 insertions(+), 33 deletions(-) diff --git a/app/admin/controller/Config.php b/app/admin/controller/Config.php index e45c3484..7e9fbe4f 100644 --- a/app/admin/controller/Config.php +++ b/app/admin/controller/Config.php @@ -99,7 +99,7 @@ class Config extends AdminBaseController public function quoteList() { $params = $this->request->param(); - if (!isset($params['page']) || !isset($params['limit'])) { + if (!isset($params['page']) || !isset($params['limit']) || !isset($params['market_type'])) { return json([ 'code' => 400, 'message' => '缺少参数', @@ -107,6 +107,24 @@ class Config extends AdminBaseController ]); } + // 检查市场类型是否有效 + if ($params['market_type'] < 0) { + return json([ + 'code' => 400, + 'message' => '市场类型无效', + 'data' => [] + ]); + } + // 根据市场类型获取数据在mongo中对应的集合名称 + if (!isset(MongoConnection::COLLECTION_ARR[$params['market_type']])) { + return json([ + 'code' => 400, + 'message' => '没有找到对应的行情数据', + 'data' => [] + ]); + } + $collectionName = MongoConnection::COLLECTION_ARR[$params['market_type']]; + // 分页计算 $page = (int)$params['page']; $pageSize = (int)$params['limit']; @@ -125,10 +143,16 @@ class Config extends AdminBaseController '$options' => 'i' ]; } + if (!empty($params['code'])) { + $filter['Code'] = trim($params['code']); + } + if (!empty($params['country'])) { + $filter['Country'] = time($params['country']); + } // 查询数据 $client = MongoConnection::getClient(); - $collection = $client->selectCollection('bourse', 'stockListBak'); + $collection = $client->selectCollection(MongoConnection::QUOTE_DATA_BASE_NAME, $collectionName); $cursor = $collection->find($filter, $options); $results = iterator_to_array($cursor); // 将 BSON 文档转换为数组 $total = $collection->countDocuments($filter); @@ -157,38 +181,84 @@ class Config extends AdminBaseController public function quoteTopData() { $params = $this->request->param(); - if (empty($params['id']) || empty($params['sort'])) { + if (empty($params['id']) || empty($params['sort']) || empty($params['market_type'])) { return json([ 'code' => 400, 'message' => '缺少参数', 'data' => [] ]); } + // 根据市场类型获取数据在mongo中对应的集合名称 + if (!isset(MongoConnection::COLLECTION_ARR[$params['market_type']])) { + return json([ + 'code' => 400, + 'message' => '没有找到对应的行情数据', + 'data' => [] + ]); + } + $collectionName = MongoConnection::COLLECTION_ARR[$params['market_type']]; + // 根据市场类型获取置顶数据将要存储的Redis Key + if (!isset(MongoConnection::QUOTE_TOP_DATA_HASH_ARR[$params['market_type']])) { + return json([ + 'code' => 400, + 'message' => '没有找到对应的行情数据存储KEY', + 'data' => [] + ]); + } + $quoteTopDataKey = MongoConnection::QUOTE_TOP_DATA_HASH_ARR[$params['market_type']]; + // 获取行情数据 $client = MongoConnection::getClient(); - $collection = $client->selectCollection('bourse', 'stockListBak'); + $collection = $client->selectCollection(MongoConnection::QUOTE_DATA_BASE_NAME, $collectionName); $doc = $collection->find(['_id'=>new ObjectId($params['id'])]); $results = iterator_to_array($doc); - if (!isset($results[0]['Code']) || !isset($results[0]['Type'])) { + + // 构建缓存数据 + $buildArr = []; + switch ($params['market_type']) { + case 3: + $buildArr = [ + 'Code' => $results[0]['Code'], + 'Type' => $results[0]['Country'], + 'Exchange' => $results[0]['Exchange'], + 'Sort' => $params['sort'], + ]; + break; + case 19: + $buildArr = [ + 'Code' => $results[0]['symbol'], // 外汇行情用symbol字段值作为Code + 'Type' => $results[0]['category'], // 外汇行情用category作为标识 + 'Sort' => $params['sort'], + ]; + break; + default: + return json([ + 'code' => 500, + 'message' => '构建数据失败', + 'data' => [] + ]); + } + + // 检测构建数据 + if (empty($buildArr)) { return json([ - 'code' => 400, - 'message' => '行情数据错误', + 'code' => 500, + 'message' => '构建数据为空', 'data' => [] ]); } - $buildArr = [ - 'Code' => $results[0]['Code'], - 'Type' => $results[0]['Type'], - 'Sort' => $params['sort'], - ]; $jsonStr = json_encode($buildArr); - - $res = Cache::store('redis')->hSet(MongoConnection::QUOTE_TOP_DATA_HASH_KEY, $results[0]['Code'], $jsonStr); + // 根据市场类型获取Redis Key + $res = Cache::store('redis')->hSet($quoteTopDataKey, $buildArr['Code'], $jsonStr); return json([ 'code' => 0, 'message' => 'ok', - 'data' => [$res] + 'data' => [ + 'cache_key' => $quoteTopDataKey, + 'cache_val' => $buildArr, + 'isOk' => $res + ] ]); } } \ No newline at end of file diff --git a/app/admin/controller/Notice.php b/app/admin/controller/Notice.php index a2505c72..6ab8ad26 100644 --- a/app/admin/controller/Notice.php +++ b/app/admin/controller/Notice.php @@ -29,6 +29,31 @@ class Notice extends AdminBaseController $title = ""; $body = ""; $res = (new \app\utility\Pusher())->publishToInterest($interestName, $title, $body); - return json($res); + return json([ + 'code' => 0, + 'message' => 'ok', + 'data' => $res + ]); + } + + // 生成Beams身份验证令牌 + public function generateToken() + { + $param = $this->request->param(); + if (empty($param['user_id'])) { + return json([ + 'code' => 400, + 'message' => "缺少参数", + 'data' => [] + ]); + } + $token = (new \app\utility\Pusher())->generateToken($param['user_id']); + return json([ + 'code' => 0, + 'message' => 'ok', + 'data' => [ + 'token' => $token + ] + ]); } } \ No newline at end of file diff --git a/app/admin/route/app.php b/app/admin/route/app.php index 6a052729..71b1e93b 100644 --- a/app/admin/route/app.php +++ b/app/admin/route/app.php @@ -34,7 +34,7 @@ Route::group('/', function () { // 消息推送 Route::post('notice/popup', 'Notice/popUp'); // 弹窗推送消息 - Route::post('notice/push_message', 'Notice/pushMessage'); // 使用Pusher推送系统级消息 + Route::post('notice/push_message', 'Notice/pushMessage'); // 使用Pusher推送设备兴趣通知 Route::post('admin/send_email_or_sms', 'Admin/sendEmailOrSms'); // 给用户发邮件或者短信 Route::post('admin/batch_send_email_or_sms', 'Admin/batchSendEmailOrSms'); // 批量给用户发邮件或者短信 diff --git a/app/home/service/WalletService.php b/app/home/service/WalletService.php index 08d27a81..a3c3fdff 100644 --- a/app/home/service/WalletService.php +++ b/app/home/service/WalletService.php @@ -1269,7 +1269,15 @@ class WalletService extends BaseHomeService break; case 19: // 巴西 - $record_list =UserForexLogModel::getUserBalanceLog($data); + $record_list = UserForexLogModel::getUserBalanceLog($data); + break; + case 20: + // 印度股指 + $record_list = UserStockIndexInrLogModel::getUserBalanceLog($data); + break; + case 21: + // 黄金期货 + $record_list = UserGoldFuturesLogModel::getUserBalanceLog($data); break; default: return $this->toData(400, lang('parameter_error')); diff --git a/app/model/UserGoldFuturesLogModel.php b/app/model/UserGoldFuturesLogModel.php index c92c2f81..5e1d891c 100644 --- a/app/model/UserGoldFuturesLogModel.php +++ b/app/model/UserGoldFuturesLogModel.php @@ -20,4 +20,25 @@ class UserGoldFuturesLogModel extends BaseModel $self->update_time = date('Y-m-d H:i:s'); return $self->save(); } + + public static function getUserBalanceLog(array $data):array + { + $where['user_id'] = $data['user_id']; + $where['contract_id'] = 'USD'; + $count = self::where($where)->count(); + if($data['page']<1){ + $data['page']=1; + } + if($data['page_size']<1){ + $data['page_size']=10; + } + $list = self::where($where)->field('change_type,contract_id as name,change_num,create_time')->order('id desc')->page($data['page'],$data['page_size'])->select(); + if(empty($list)){ + return []; + } + return [ + 'total'=>$count, + 'list'=>$list->toArray(), + ]; + } } \ No newline at end of file diff --git a/app/model/UserStockIndexInrLogModel.php b/app/model/UserStockIndexInrLogModel.php index b12aec21..f858f71d 100644 --- a/app/model/UserStockIndexInrLogModel.php +++ b/app/model/UserStockIndexInrLogModel.php @@ -22,4 +22,25 @@ class UserStockIndexInrLogModel extends BaseModel return $self->save(); } + public static function getUserBalanceLog(array $data):array + { + $where['user_id'] = $data['user_id']; + $where['contract_id'] = 'INR'; + $count = self::where($where)->count(); + if($data['page']<1){ + $data['page']=1; + } + if($data['page_size']<1){ + $data['page_size']=10; + } + $list = self::where($where)->field('change_type,contract_id as name,change_num,create_time')->order('id desc')->page($data['page'],$data['page_size'])->select(); + if(empty($list)){ + return []; + } + return [ + 'total'=>$count, + 'list'=>$list->toArray(), + ]; + } + } \ No newline at end of file diff --git a/app/utility/MongoConnection.php b/app/utility/MongoConnection.php index 1ae3e808..0674c600 100644 --- a/app/utility/MongoConnection.php +++ b/app/utility/MongoConnection.php @@ -5,7 +5,18 @@ use MongoDB\Client; class MongoConnection { - const QUOTE_TOP_DATA_HASH_KEY = 'QUOTE_TOP_DATA_HASH'; + const QUOTE_DATA_BASE_NAME = 'bourse'; // 各类行情数据存储在mongodb中的数据库名称 + const QUOTE_TOP_DATA_HASH_ARR = [ + '3' => 'QUOTE_TOP_DATA_HASH_STOCK', //股票行情置顶数据Key + '19' => 'QUOTE_TOP_DATA_HASH_FOREX' //外汇行情置顶数据Key + ]; + // mongo中存储各类行情的集合名称 + const COLLECTION_ARR = [ + '3' => 'stockListBak', // 美股行情 + '19' => 'forexListBak' // 外汇行情 + ]; + + private static $client = null; public static function getClient() { diff --git a/app/utility/Pusher.php b/app/utility/Pusher.php index 215b984a..baa8d73c 100644 --- a/app/utility/Pusher.php +++ b/app/utility/Pusher.php @@ -7,20 +7,29 @@ use Pusher\PushNotifications\PushNotifications; require_once __DIR__ . '/../../vendor/autoload.php'; class Pusher extends BaseHomeService { - // 发送到所有订阅兴趣的客户端 $interest 必须是数组类型,可以包含多个兴趣名称 + private static $client = null; + + public static function getClient() { + if (self::$client === null) { + self::$client = new \Pusher\PushNotifications\PushNotifications( + array( + "instanceId" => env('PUSHER.INSTANCE_ID'), + "secretKey" => env('PUSHER.SECRET_KEY'), + ) + ); + } + return self::$client; + } + + // 向一个或多个设备兴趣发布推送通知 $interest 必须是数组类型Array,可以包含多个兴趣名称 public function publishToInterest($interest, $title, $body) { - $beamsClient = new \Pusher\PushNotifications\PushNotifications( - array( - "instanceId" => env('PUSHER.INSTANCE_ID'), - "secretKey" => env('PUSHER.SECRET_KEY'), - ) - ); + $beamsClient = self::getClient(); return $beamsClient->publishToInterests( $interest, // 兴趣名称最多100个 [ "apns" => [ - "aps" => [ + 'aps' => [ "alert" => [ "title" => $title, "body" => $body @@ -46,12 +55,7 @@ class Pusher extends BaseHomeService // 发送到指定用户, 用户列表必须是数组,最大长度1000个用户 public function publishToUsers($userArr, $title, $body) { - $beamsClient = new \Pusher\PushNotifications\PushNotifications( - array( - "instanceId" => env('PUSHER.INSTANCE_ID'), - "secretKey" => env('PUSHER.SECRET_KEY'), - ) - ); + $beamsClient = self::getClient(); return $beamsClient->publishToUsers( // array("user-001", "user-002"), $userArr, @@ -78,5 +82,11 @@ class Pusher extends BaseHomeService ); } + // 生成Beams身份验证令牌,该令牌有效期为24小时 (客户端需要拿这个Token去请求Beams关联设备与用户ID) 注意:每个平台每个用户在任意时刻最多可关联100台设备,当用户退出应用时,可以调用客户端SDK中的.stop方法理解解除关联关系。 + public function generateToken($userId) + { + $beamsClient = self::getClient(); + return $beamsClient->generateToken($userId); + } } \ No newline at end of file