From 246dc8732e989ba505a4c60db37da25558d3f1da Mon Sep 17 00:00:00 2001 From: chuan <2154243450@qq.com> Date: Wed, 5 Mar 2025 14:24:54 +0800 Subject: [PATCH] stock analysis --- app/home/controller/Stock.php | 8 +++ app/home/route/app.php | 5 +- app/home/service/LoginService.php | 2 +- app/home/service/StockService.php | 72 ++++++++++++++++++++++++++ app/home/service/UserVerifyService.php | 6 +-- app/utility/HttpHandler.php | 32 ++++++++++++ 6 files changed, 119 insertions(+), 6 deletions(-) create mode 100644 app/utility/HttpHandler.php diff --git a/app/home/controller/Stock.php b/app/home/controller/Stock.php index a0c3e91b..a287ffea 100644 --- a/app/home/controller/Stock.php +++ b/app/home/controller/Stock.php @@ -14,4 +14,12 @@ class Stock extends HomeBaseController $result = $service->checkMarketStatus($this->request->param()); return json($result); } + + // 股票分析 + public function stockAnalysis() + { + $service = new StockService(); + $result = $service->stockAnalysis($this->request->userId, $this->request->param()); + return json($result); + } } \ No newline at end of file diff --git a/app/home/route/app.php b/app/home/route/app.php index c940381d..38d8a631 100644 --- a/app/home/route/app.php +++ b/app/home/route/app.php @@ -77,7 +77,6 @@ Route::group('/',function (){ // 获取股票市场状态 Route::post('/stock/check_status', 'Stock/checkMarketStatus'); - //Route::post('payment_test', 'Pay/test'); //获取充值渠道 Route::post('indpay_notify', 'Pay/indPayNotify')->name('indpay_notify'); //支付异步通知地址 Route::post('indpay_query', 'Pay/indPayQuery')->name('indpay_query'); //支付同步通知地址 @@ -276,6 +275,8 @@ Route::group('/',function (){ Route::post('video/video_on_demand_detail', 'Video/videoOnDemandDetail'); // 获取某个点播配置详情 Route::post('video/blocked_word_list', 'Video/blockedWordList'); //获取屏蔽词列表 + Route::post('stock/stock_analysis', 'Stock/stockAnalysis'); // 股票分析 + })->middleware(\app\home\middleware\AuthMiddleware::class); // 美股申购列表 不需要登陆 @@ -288,7 +289,7 @@ Route::group('/',function (){ Route::post('get_ip', 'Login/getIP'); Route::get('get_news', 'News/index'); - Route::post('test', 'User/apiCalledNumCheck'); + Route::post('test', 'Stock/stockAnalysis'); })->allowCrossDomain($header); diff --git a/app/home/service/LoginService.php b/app/home/service/LoginService.php index 8d66eef9..756b9999 100644 --- a/app/home/service/LoginService.php +++ b/app/home/service/LoginService.php @@ -190,7 +190,7 @@ class LoginService extends BaseHomeService 'user_no' => $userNo, 'nick_name' => $userNickName ?? 'user_' . time(), 'email' => $email, - 'phone' => $phone, + 'phone_number' => $phone, 'invite_code' => $userInviteCode, 'parent_id' => $parentUserId, 'agent_id' => $agentId, diff --git a/app/home/service/StockService.php b/app/home/service/StockService.php index 6c69e8df..199a872f 100644 --- a/app/home/service/StockService.php +++ b/app/home/service/StockService.php @@ -2,7 +2,11 @@ namespace app\home\service; +use app\model\ApiCalledNumModel; +use app\model\PurchaseVipModel; use app\model\StockMarketModel; +use app\utility\HttpHandler; +use think\facade\Log; class StockService extends BaseHomeService { @@ -64,4 +68,72 @@ class StockService extends BaseHomeService } } + + public function stockAnalysis($userId,$param){ + try { + if (empty($userId)) { + return $this->toData('400','用户ID不能为空'); + + } + if (empty($param['stock_code'])) { + return $this->toData('400','缺少参数'); + } + + // 检测用户调用该接口次数,普通用户只能调用5次,vip用户可以无限次调用 + $apiCalledNum = ApiCalledNumModel::where(['user_id'=>$userId])->find(); + if (!empty($apiCalledNum) && $apiCalledNum->stock_api >= ApiCalledNumModel::API_CALLED_LIMIT) { + $vipInfo = PurchaseVipModel::where(['user_id'=>$userId])->find(); + if (empty($vipInfo)) { + return $this->toData('400', '非会员用户只能使用5次股票分析接口'); + } else { + if ($vipInfo->expire <= date("Y-m-d H:i:s")) { + return $this->toData('400', '非会员用户只能使用5次股票分析接口'); + } + } + } + + $replaceData = [ + '{stock_code}' => $param['stock_code'] + ]; + $msgTml = "1. 获取{stock_code}的最新股价、市场情绪及相关新闻。2. 结合过去 30 天的价格走势,预测未来 7 天的短期趋势。3. 提供投资建议(买入、持有或卖出),并说明理由。4. 如果可能,引用具体数据或事件支持你的分析。"; + $msg = str_replace(array_keys($replaceData), array_values($replaceData), $msgTml); + $headers = [ + 'Content-Type' => 'application/json', + 'Authorization' => 'Bearer xai-X2H9moLMSKQaCMsfnjZxjfvHeRd0O3Q8zBfJ3I3sEOSIYd8840zsUvUWkj6g2rxy5VfRMRF87YkSsE85', + 'cf-aig-authorization' => 'Bearer RCnKINIJTYVgFIbJjPznXekn0SV94GRVIait3-vO', + ]; + $reqData = [ + 'model' => 'grok-2-1212', +// 'max_tokens' => 500, //会限制输出结果长度 + 'temperature' => 0.6, + 'messages' => [ + [ + 'role' => 'user', + 'content' => $msg + ] + ], + ]; + $url = "https://gateway.ai.cloudflare.com/v1/14aa58d158b80afdedd874eb4bc82636/chatgpt-api/grok/v1/chat/completions"; + $result = HttpHandler::reqPost($url, $headers, $reqData); + if ($result['code'] != 200) { + return $this->toData('500', '数据错误,稍后再试', $result); + } + $getBody = json_decode($result['data'], true); + $getChoices = $getBody['choices']; + + // 更新用户调用该接口次数 + if (empty($apiCalledNum)) { + ApiCalledNumModel::create([ + 'user_id' => $userId, + 'stock_api' => 1 + ]); + } else { + ApiCalledNumModel::where(['user_id'=>$userId])->inc('stock_api')->save(); + } + + return $this->toData('0', 'success', $getChoices); + } catch (\Exception $exception){ + return $this->toData('500','System error',[$exception->getMessage()]); + } + } } \ No newline at end of file diff --git a/app/home/service/UserVerifyService.php b/app/home/service/UserVerifyService.php index 33bb9f9a..efd1ceb6 100644 --- a/app/home/service/UserVerifyService.php +++ b/app/home/service/UserVerifyService.php @@ -2,11 +2,11 @@ namespace app\home\service; +use app\model\AwsS3Model; use app\model\CountryModel; use app\model\FileModel; use app\model\UserModel; use app\model\UserVerifyLogModel; -use app\utility\UnqId; class UserVerifyService extends BaseHomeService { @@ -112,8 +112,8 @@ class UserVerifyService extends BaseHomeService $data = []; if(!empty($log)){ - $front = FileModel::where('id', $log->front_img)->value('path'); - $back = FileModel::where('id', $log->back_img)->value('path'); + $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, diff --git a/app/utility/HttpHandler.php b/app/utility/HttpHandler.php new file mode 100644 index 00000000..bc8d4e91 --- /dev/null +++ b/app/utility/HttpHandler.php @@ -0,0 +1,32 @@ +post($url, [ + 'headers' => $headers, + 'json' => $data, + ]); + $statusCode = $response->getStatusCode(); + $getBody = $response->getBody()->getContents(); + Log::info("HttpHandler - 请求结果:statusCode==".$statusCode." getBody==".$getBody); + return ['code'=>$statusCode, 'message'=>'', 'data'=>$getBody]; + } catch (GuzzleException $e) { + Log::error("HttpHandler - 请求异常 - guzzle: " . $e->getMessage()); + return ['code'=>500, 'message'=>$e->getMessage()]; + } catch (\Exception $exception) { + Log::error("HttpHandler - 请求异常 - exception: " . $exception->getMessage()); + return ['code'=>500, 'message'=>$exception->getMessage()]; + } + } +} \ No newline at end of file