From 1754ad75913f8aa259e97f9f71523b884c37d439 Mon Sep 17 00:00:00 2001 From: chuan <2154243450@qq.com> Date: Mon, 10 Mar 2025 12:30:19 +0800 Subject: [PATCH] up --- app/admin/controller/Test.php | 10 +- app/admin/controller/Upload.php | 172 +++++++++++++++------ app/admin/controller/User.php | 13 ++ app/admin/controller/setting/Forex.php | 28 ++++ app/admin/route/app.php | 4 +- app/admin/service/AdminBaseService.php | 26 ++++ app/admin/service/AgentService.php | 29 ++-- app/admin/service/UserService.php | 110 ++++++++++++- app/admin/service/setting/ForexService.php | 162 +++++++++++++++++++ app/admin/service/setting/IPOService.php | 15 ++ app/home/job/SendEmail.php | 6 +- app/home/job/SendSms.php | 30 ++-- app/home/service/LoginService.php | 42 ++--- app/home/service/StockService.php | 19 ++- app/home/service/UserService.php | 8 +- app/model/AdminModel.php | 6 +- app/model/ForexMarketModel.php | 11 ++ composer.json | 3 +- 18 files changed, 554 insertions(+), 140 deletions(-) create mode 100644 app/model/ForexMarketModel.php diff --git a/app/admin/controller/Test.php b/app/admin/controller/Test.php index 3574e2cf..f2af2c94 100644 --- a/app/admin/controller/Test.php +++ b/app/admin/controller/Test.php @@ -8,13 +8,21 @@ class Test extends AdminBaseController public function index() { + $appRootPath = app()->getRootPath(); + $appAppPath = app()->getAppPath(); $memoryLimit = ini_get('memory_limit'); $uploadMax = ini_get('upload_max_filesize'); $postMax = ini_get('post_max_size'); + $max_execution_time = ini_get('max_execution_time'); //最大执行时间(秒) + $max_input_time = ini_get('max_input_time'); // 输入解析时间限制 return json(['code' => '0', 'msg' => 'SUCCESS', 'data' => [ 'memory_limit' => $memoryLimit, 'upload_max' => $uploadMax, - 'post_max' => $postMax + 'post_max' => $postMax, + 'max_execution_time' => $max_execution_time, + 'max_input_time' => $max_input_time, + 'app_root_path' => $appRootPath, + 'app_path' => $appAppPath, ]]); } } \ No newline at end of file diff --git a/app/admin/controller/Upload.php b/app/admin/controller/Upload.php index bf7cdccd..c7c6fdb2 100644 --- a/app/admin/controller/Upload.php +++ b/app/admin/controller/Upload.php @@ -7,6 +7,7 @@ use app\model\FileModel; use Aws\S3\S3Client; use think\facade\Filesystem; use think\facade\Config; +use think\facade\Log; class Upload extends AdminBaseController { @@ -20,11 +21,16 @@ class Upload extends AdminBaseController if (!$file) { return json(['code' => 400, 'message' => 'No file uploaded']); } - // 验证文件类型和大小 - $maxSize = 15 * 1024 * 1024; //限制M + // 验证文件类型和大小, 限制20M + $maxSize = 20 * 1024 * 1024; if ($file->getSize() > $maxSize) { return json(['code' => 400, 'message' => 'Upload file is too large']); } + // 打开文件 + $openFile = fopen($file->getRealPath(), 'r'); + if (!$openFile) { + return json(['code' => 400, 'message' => 'Failed to open the file']); + } // 验证上传文件类型 if (!in_array($file->getOriginalMime(), ['image/jpeg','image/png','image/webp','image/bm'])) { return json(['code' => 400, 'message' => 'Upload file type error']); @@ -45,10 +51,10 @@ class Upload extends AdminBaseController $result = $s3Client->putObject([ 'Bucket' => $s3Config['aws_bucket'], 'Key' => 'bourse-avatar/' . $fileName, // s3中的存储路径 - 'Body' => fopen($file->getRealPath(), 'r'), + 'Body' => $openFile, 'ContentType' => $file->getOriginalMime(), // 设置文件的MIME, 不然s3会以流式存储 - ]); - if (empty($result) || empty($result['ObjectURL'])) { + ])->toArray(); + if (empty($result['ObjectURL'])) { return json(['code' => 400, 'message' => '上传s3失败']); } // 记录上传的文件 @@ -59,10 +65,13 @@ class Upload extends AdminBaseController 'mime' => $file->getOriginalMime(), 'ext' => $file->getOriginalExtension(), ]); - + fclose($openFile); // 返回路径 return json(['code' => '0', 'message' => '上传成功', 'data' => ['path' => $resData->s3_url]]); } catch (\Exception $exception) { + if (isset($openFile)) { + fclose($openFile); + } return json(['code' => '100500', 'message' => '系统繁忙', 'data' => [$exception->getMessage()]]); } } @@ -77,11 +86,16 @@ class Upload extends AdminBaseController if (!$file) { return json(['code' => 400, 'message' => 'No file uploaded']); } - // 验证文件类型和大小 - $maxSize = 1024 * 1024 * 1024; //限制1G + // 验证文件类型和大小 限制100M + $maxSize = 100 * 1024 * 1024; if ($file->getSize() > $maxSize) { return json(['code' => 400, 'message' => 'The file size cannot exceed 1 GB']); } + // 打开文件 + $openFile = fopen($file->getRealPath(), 'r'); + if (!$openFile) { + return json(['code' => 400, 'message' => 'Failed to open the file']); + } // 生成唯一的文件名 $fileName = bin2hex(random_bytes(16)) . '.' . $file->getOriginalExtension(); // 初始化s3客户端 @@ -99,12 +113,14 @@ class Upload extends AdminBaseController $result = $s3Client->putObject([ 'Bucket' => $s3Config['aws_bucket'], 'Key' => 'bourse-video-node/' . $fileName, // s3中的存储路径 - 'Body' => fopen($file->getRealPath(), 'r'), + 'Body' => $openFile, 'ContentType' => $file->getOriginalMime(), // 设置文件的MIME, 不然s3会以流式存储 // 'ACL' => 'public-read', // 设置文件为公开可读 - ]); - if (empty($result) || empty($result['ObjectURL'])) { - return json(['code' => 400, 'message' => '上传s3失败']); + ])->toArray(); + fclose($openFile); + Log::info("上传s3结果:". json_encode($result)); + if (empty($result['ObjectURL'])) { + return json(['code' => 400, 'message' => '上传失败']); } // 记录上传的文件 $resData = AwsS3Model::create([ @@ -124,30 +140,44 @@ class Upload extends AdminBaseController 'ext'=> $file->getOriginalExtension(), ]]); } catch (\Exception $exception) { + if (isset($openFile)) { + fclose($openFile); + } return json(['code' => '100500', '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 { - $param = $this->request->param(); - if (empty($param['file_type'])) { - return json(['code' => '100500', 'message' => '缺少参数 file_type', 'data' => []]); - } - // 允许的视频类型 - $allowed_types = [ - 'video/mp4', - 'video/quicktime', - 'video/x-msvideo', - 'video/x-ms-wmv', - 'video/x-matroska', - ]; - if (!in_array($param['file_type'], $allowed_types)) { - return json(['code' => '100500', 'message' => '上传的文件类型不在允许范围内', 'data' => []]); + $param = $this->request->post(); + if (empty($param['mime'])) { + return json(['code' => 400, 'message' => '缺少参数mime']); + } + $getMime = trim($param['mime']); + // 获取文件扩展名 + $mimeArr = explode('/', $getMime); + $getExt = end($mimeArr); + if (empty($getExt)) { + return json(['code' => 400, 'message' => '提取文件扩展名错误']); } // 生成唯一的文件名 - $fileName = bin2hex(random_bytes(16)); + $fileName = bin2hex(random_bytes(16)) . '.' . $getExt; // 初始化s3客户端 $s3Config = Config::get('common.aws_s3'); $s3Client = new S3Client([ @@ -158,24 +188,38 @@ class Upload extends AdminBaseController 'secret' => $s3Config['aws_secret'], ], ]); - // 初始化Multipart Upload + // 初始化分段上传,获取上传Id $result = $s3Client->createMultipartUpload([ 'Bucket' => $s3Config['aws_bucket'], 'Key' => 'bourse-video-node/' . $fileName, + 'ContentType' => $getMime, + ])->toArray(); + Log::info("初始化分段上传结果:".json_encode($result)); + if (empty($result['UploadId'])) { + return json(['code' => 500, 'message' => '初始化分片上传失败','data'=>$result]); + } + AwsS3Model::create([ + 'upload_id' => $result['UploadId'], + 'key' => 'bourse-video-node/' . $fileName, + 'name' => $fileName, + 'mime' => $getMime, + 'ext' => $getExt, ]); + return json([ 'code' => 0, + 'message' => 'success', 'data' => [ 'uploadId' => $result['UploadId'], 'key' => $result['Key'] ] ]); } catch (\Exception $exception) { - return json(['code' => '100500', 'message' => '初始化上传失败', 'data' => [$exception->getMessage()]]); + return json(['code' => '500', 'message' => '初始化分段上传失败', 'data' => [$exception->getMessage()]]); } } - // 上传分片 + // 上传每个分段 public function uploadPart(){ try { $param = $this->request->param(); @@ -186,6 +230,15 @@ class Upload extends AdminBaseController if (!$file) { return json(['code' => 400, 'message' => 'No file uploaded']); } + // 每个分段大小限制 最大50M + if ($file->getSize() > 100 * 1024 * 1024) { + return json(['code' => 400, 'message' => 'File size is too large for multipart upload']); + } + // 打开文件 + $openFile = fopen($file->getRealPath(), 'r'); + if (!$openFile) { + return json(['code' => 400, 'message' => 'Failed to open file']); + } // 初始化s3客户端 $s3Config = Config::get('common.aws_s3'); $s3Client = new S3Client([ @@ -201,28 +254,43 @@ class Upload extends AdminBaseController 'Key' => $param['key'], 'PartNumber' => $param['partNumber'], 'UploadId' => $param['uploadId'], - 'Body' => fopen($file->getRealPath(), 'r'), - ]); - + 'Body' => $openFile, + ])->toArray(); + fclose($openFile); + Log::info("上传分段结果:".json_encode($result)); return json([ 'code' => 200, + 'message' => 'success', 'data' => [ - 'ETag' => $result['ETag'], - 'PartNumber' => $param['partNumber'] + 'ETag' => $result['ETag'], // 每个分段的ETag + 'PartNumber' => $param['partNumber'], + 'key' => $param['key'], // 存储在s3桶中的key ] ]); } catch (\Exception $exception) { + if (isset($openFile)) { + fclose($openFile); + } return json(['code' => '100500', 'message' => '上传失败', 'data' => [$exception->getMessage()]]); } } - // 完成上传 + // 完成分段上传 public function completeUpload(){ try { $param = $this->request->param(); - if (empty($param['uploadId']) || empty($param['key']) || empty($param['parts'])) { + if (empty($param['uploadId']) || empty($param['key'])) { return json(['code' => 400, 'message' => '缺少参数']); } + if (empty($param['parts']) || !is_array($param['parts'])) { + return json(['code' => 400, 'message' => 'parts参数错误']); + } + // 注意:$parts 是一个数组,里面需要有每个分段编号,以及每个分段对应的ETag +// $parts = [ +// ['PartNumber' => 1, 'ETag' => 'etag-for-part-1'], +// ['PartNumber' => 2, 'ETag' => 'etag-for-part-2'], +// ]; + // 初始化s3客户端 $s3Config = Config::get('common.aws_s3'); $s3Client = new S3Client([ @@ -233,22 +301,38 @@ class Upload extends AdminBaseController 'secret' => $s3Config['aws_secret'], ], ]); - $s3Client->completeMultipartUpload([ + $result = $s3Client->completeMultipartUpload([ 'Bucket' => $s3Config['aws_bucket'], 'Key' => $param['key'], 'UploadId' => $param['uploadId'], 'MultipartUpload' => [ 'Parts' => $param['parts'] ], - ]); + ])->toArray(); + Log::info("完成分段上传结果:".json_encode($result)); - return json(['code' => 200, 'message' => '上传成功']); + // 更新分片上传记录 + $awsS3 = AwsS3Model::where(['upload_id'=>$param['uploadId']])->find(); + if (empty($awsS3)) { + return json(['code' => 500, 'message' => '数据记录错误']); + } + $awsS3->is_complete = 1; + $awsS3->parts = json_encode($param['parts']); + $awsS3->s3_url = $result['Location']; + $awsS3->save(); + + return json(['code' => 200, 'message' => '上传成功', 'data'=>[ + 'id' => $awsS3->id, + 'uploadId' => $param['uploadId'], + 'key' => $param['key'], + 'location' => $result['Location'], + ]]); } catch (\Exception $exception) { return json(['code' => '100500', 'message' => '完成上传失败', 'data' => [$exception->getMessage()]]); } } - // 取消上传 + // 中止分段上传 public function abortUpload(){ try { $param = $this->request->param(); @@ -265,12 +349,12 @@ class Upload extends AdminBaseController 'secret' => $s3Config['aws_secret'], ], ]); - $s3Client->abortMultipartUpload([ + $result = $s3Client->abortMultipartUpload([ 'Bucket' => $s3Config['aws_bucket'], 'Key' => $param['key'], 'UploadId' => $param['uploadId'], ]); - + Log::info('终止分段上传结果:'.json_encode($result)); return json(['code' => 200, 'message' => '上传已取消']); } catch (\Exception $exception) { return json(['code' => '100500', 'message' => '取消上传失败', 'data' => [$exception->getMessage()]]); diff --git a/app/admin/controller/User.php b/app/admin/controller/User.php index 9e352b44..c1894776 100644 --- a/app/admin/controller/User.php +++ b/app/admin/controller/User.php @@ -72,6 +72,19 @@ class User extends AdminBaseController return json($result); } + public function get_loan() + { + $service = new UserService(); + $result = $service->getUserLoan($this->request->param(),$this->getAdminId()); + return json($result); + } + public function deal_loan() + { + $service = new UserService(); + $result = $service->dealUserLoan($this->request->param(),$this->getAdminId()); + return json($result); + } + ##################### 查看验证码 public function getUserCode() { diff --git a/app/admin/controller/setting/Forex.php b/app/admin/controller/setting/Forex.php index eda8c686..29b99934 100644 --- a/app/admin/controller/setting/Forex.php +++ b/app/admin/controller/setting/Forex.php @@ -44,6 +44,34 @@ class Forex extends AdminBaseController return json($result); } + public function hq_index() + { + $service = new ForexService(); + $result = $service->hq_index(); + return json($result); + } + + public function hq_add() + { + $service = new ForexService(); + $result = $service->hq_add($this->request->param()); + return json($result); + } + + public function hq_edit() + { + $service = new ForexService(); + $result = $service->hq_edit($this->request->param()); + return json($result); + } + + public function hq_del() + { + $service = new ForexService(); + $result = $service->hq_del($this->request->param()); + return json($result); + } + public function set_add() { $service = new ForexService(); diff --git a/app/admin/route/app.php b/app/admin/route/app.php index a99d19ed..bef8b29f 100644 --- a/app/admin/route/app.php +++ b/app/admin/route/app.php @@ -14,7 +14,7 @@ $header = [ //Route::get('/test', 'Test/index'); Route::post('/test', 'Test/index'); Route::post('/test_upload', 'Upload/uploadVideo'); -Route::post('test_api', 'Admin/sendEmailOrSms'); +Route::post('test_api', 'Agent/customerUserList'); Route::group('/', function () { // 上传图片 Route::post('/upload', 'Upload/upload'); @@ -179,7 +179,7 @@ Route::group('/', function () { Route::post('/agent/user', 'Agent/user'); Route::post('/agent/manager', 'Agent/manager'); Route::post('/agent/customer_list', 'Agent/customerList'); //客服列表,支持搜索某个代理下的客服 - Route::post('/agent/customer_user_list', 'Agent/customerUserList'); //获取客服下所有用户 + Route::post('agent/customer_user_list', 'Agent/customerUserList'); //获取客服下所有用户 Route::post('/agent/change_user_customer', 'Agent/changeUserCustomer')->middleware('admin_log'); //变更用户绑定的客服 Route::post('/agent/aws_ivs_list', 'Agent/awsIvsList'); //直播推流列表 Route::post('/agent/aws_ivs_add', 'Agent/awsIvsAdd')->middleware('admin_log'); //直播推流配置添加 diff --git a/app/admin/service/AdminBaseService.php b/app/admin/service/AdminBaseService.php index 9670362d..a2ed6de3 100644 --- a/app/admin/service/AdminBaseService.php +++ b/app/admin/service/AdminBaseService.php @@ -5,6 +5,7 @@ namespace app\admin\service; use app\model\AdminModel; use app\model\ContractMarketModel; use app\model\ContractSettingModel; +use app\model\ForexMarketModel; use GuzzleHttp\Client; use GuzzleHttp\Exception\GuzzleException; use think\db\exception\PDOException; @@ -380,6 +381,31 @@ class AdminBaseService $redis->set($reds_key, json_encode($rows)); } + // 外汇插针缓存 + public function initForexHqData() + { + $now = date('Y-m-d H:i:s'); + $list = ForexMarketModel::where('type', 0) + ->whereTime('begin_time', '>', $now) + ->field('trade_name as selfContractCode,begin_time as BeginTime,step as Step ,end_time as EndTime,max_price as Price') + ->order('id', 'desc') + ->select(); + $rows = []; + $redis = $this->getRedis(); + if (!$list->isEmpty()) { + $rows = $list->toArray(); + foreach ($rows as $key => $val) { + $keep_decimal = $redis->hget('FOREX:LIST:' . $val['selfContractCode'], 'keep_decimal'); + $list[$key]['Digits'] = $keep_decimal; + } + } + + $reds_key = "forex_hq_setting"; + $redis->del($reds_key); + $redis->set($reds_key, json_encode($rows)); + } + + public function initContractSetting() { $list = ContractSettingModel::getSettingList(); diff --git a/app/admin/service/AgentService.php b/app/admin/service/AgentService.php index 92d83f25..d9b7fa9f 100644 --- a/app/admin/service/AgentService.php +++ b/app/admin/service/AgentService.php @@ -4,10 +4,8 @@ namespace app\admin\service; use app\model\AdminModel; use app\model\AgentChannelListModel; -use app\model\AuthGroupAccessModel; use app\model\AuthRoleModel; use app\model\AwsIvsModel; -use app\model\CustomerRelationalModel; use app\model\ForexTradeModel; use app\model\PurchaseVipModel; use app\model\RechargeApplyModel; @@ -212,24 +210,17 @@ class AgentService extends AdminBaseService if (empty($param['customer_id']) || !is_numeric($param['customer_id'])) { return $this->toData('400', '参错错误'); } - if (empty($param['page']) || !is_numeric($param['page'])) { + if (empty($param['page']) || empty($param['limit'])) { return $this->toData('400', '参错错误'); } // 查询当前客服下的用户 - $list = CustomerRelationalModel::where('customer_id', $param['customer_id'])->order('id', 'desc')->paginate([ + $list = UserModel::where('customer_id', $param['customer_id'])->order('user_id', 'desc')->paginate([ 'list_rows' => $param['limit'], 'page' => $param['page'], // 使用前端传递的页码 ]); - $userIds = array_column($list->items(), 'user_id'); // 获取当前页的用户id - // 根据user_id查询用户列表 - $userDetails = []; - if ($userIds) { - $userDetails = UserModel::whereIn('user_id', $userIds)->select()->toArray(); - } return $this->toData('0', 'success', [ 'list' => $list->items(), // 当前页的数据 - 'user_details' => $userDetails, 'page' => $list->currentPage(), // 当前页码 'total' => $list->total(), // 总记录数 'last_page' => $list->lastPage(), // 最后一页页码 @@ -246,21 +237,21 @@ class AgentService extends AdminBaseService return $this->toData('400', '参数错误'); } - $cstRlt = CustomerRelationalModel::where(['user_id'=>$param['user_id'], 'customer_id'=>$param['old_customer_id']])->find(); - if (empty($cstRlt)) { - return $this->toData('500', '操作的数据不存在'); + $user = UserModel::where(['user_id'=>$param['user_id']])->find(); + if (empty($user)) { + return $this->toData('500', '用户数据为空'); } // 变更的客服必须是同一个代理 $newCustomer = AdminModel::where(['id'=>$param['new_customer_id']])->find(); if (empty($newCustomer)) { - return $this->toData('500', '要变更的客服不存在'); + return $this->toData('500', '客服数据错误'); } - if ($newCustomer->parent_id != $cstRlt->agent_id) { - return $this->toData('500', '新客服不属于同一个代理'); + if ($newCustomer->parent_id != $user->agent_id) { + return $this->toData('500', '变更的客服不属于同一个代理'); } // 变更客服绑定关系 - $cstRlt->customer_id = $param['new_customer_id']; - $cstRlt->save(); + $user->customer_id = $param['new_customer_id']; + $user->save(); // 将用户与新客服的聊天账号加好友 $userChatInfo = UserChatLinkModel::where(['user_id'=>$param['user_id'], 'user_type'=>UserChatLinkModel::USER_CHAT_LINK_USER_TYPE_PC])->find(); diff --git a/app/admin/service/UserService.php b/app/admin/service/UserService.php index caf9df59..f37cf857 100644 --- a/app/admin/service/UserService.php +++ b/app/admin/service/UserService.php @@ -6,10 +6,9 @@ use app\admin\validate\UserValidate; use app\home\service\BaseHomeService; use app\model\AccountFrozenModel; use app\model\AdminModel; +use app\model\AuthRoleModel; use app\model\AwsS3Model; use app\model\CountryModel; -use app\model\CustomerRelationalModel; -use app\model\FileModel; use app\model\StockMarketModel; use app\model\UserBankModel; use app\model\UserChatLinkModel; @@ -17,6 +16,7 @@ use app\model\UserContractModel; use app\model\UserContractSecModel; use app\model\UserDigitalModel; use app\model\UserForexModel; +use app\model\UserLoanModel; use app\model\UserLoginLog; use app\model\UserModel; use app\model\UserStageStateModel; @@ -38,7 +38,6 @@ use app\model\UserStockFundModel; use think\exception\ValidateException; use app\utility\UnqId; use think\facade\Cache; -use think\facade\Log; class UserService extends AdminBaseService { @@ -51,6 +50,27 @@ class UserService extends AdminBaseService validate(UserValidate::class)->scene('index')->check($param); $where = []; + + // 角色数据权限过滤: 管理员登录可查看所有用户数据;代理登录查看代理下用户数据;客服登录查看客服关联用户的数据 + $account = AdminModel::where(['id'=>$adminId])->find(); + if (empty($account)) { + return $this->toData('500', '当前账号数据错误'); + } + $role = AuthRoleModel::where(['id'=>$account->role_id])->find(); + if (empty($role)) { + return $this->toData('500', '当前角色数据错误'); + } + + // 如果是代理,过滤代理下的用户 + if ($role->name == AuthRoleModel::NAME_AGENT) { + $where['agent_id'] = $adminId; + } + // 如果是客服,过滤客服下的用户 + if ($role->name == AuthRoleModel::NAME_CUSTOMER) { + $where['customer_id'] = $adminId; + } + + // base_label过滤 if (!empty($param['base_label'])) { $where['base_label'] = trim($param['base_label']); @@ -134,11 +154,15 @@ class UserService extends AdminBaseService $rows = []; $userIdArr = []; $parentIdArr = []; + $customerRelationList = []; foreach ($userList as $value) { $userIdArr[] = $value['user_id']; if ($value['parent_id'] > 0) { $parentIdArr[] = $value['parent_id']; } + if (!empty($value['customer_id'])) { + $customerRelationList[$value['user_id']] = $value['customer_id']; + } } // 查询父级 @@ -219,8 +243,6 @@ class UserService extends AdminBaseService ->where('contract_id', 'USD') ->column('usable_num,frozen_num', 'user_id'); - // 用户关联的客服id - $customerRelationList = CustomerRelationalModel::where('user_id', 'in', $userIdArr)->column('customer_id', 'user_id'); // 获取每个客服的名称 $customerNames = []; if ($customerRelationList) { @@ -879,6 +901,84 @@ class UserService extends AdminBaseService } } + public function getUserLoan($param,$adminId) + { + try { + $where = []; + $userId = 0; + // 用户号精确搜索 + if (!empty($param['user_no'])) { + $user = UserModel::where('user_no', $param['user_no'])->find(); + if (empty($user)) { + return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]); + } + $userId = $user['user_id']; + } + + // 判断是否是代理 如果是代理 只能看他自己管理的用户 + $where = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId); + + if(isset($param['status'])){ + $where['status']=intval($param['status']); + } + + $data['where']=$where; + + $data['page']=isset($param['page']) ? intval($param['page']) : 1; + $data['size']=isset($param['size']) ? intval($param['size']) : 10; + + $list = UserLoanModel::getUserLoanList($data); + if(!empty($list['list'])){ + foreach ($list['list'] as $key=>$item){ + $user= UserModel::where('user_id', $item['user_id'])->find(); + $list['list'][$key]['nick_name']=$user->nick_name; + } + } + + return $this->toData('0', 'SUCCESS', $list); + } catch (\Exception $exception) { + return $this->toData('1', '系统繁忙', [$exception->getMessage(),$exception->getTrace()]); + } + } + + public function dealUserLoan($param,$adminId) + { + try { + $where = []; + $userId = 0; + // 用户号精确搜索 + if (!empty($param['user_no'])) { + $user = UserModel::where('user_no', $param['user_no'])->find(); + if (empty($user)) { + return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]); + } + $userId = $user['user_id']; + } + + // 判断是否是代理 如果是代理 只能看他自己管理的用户 + $where = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId); + + $where['id']=intval($param['id']); + + $info=UserLoanModel::where($where)->find(); + if(empty($info)){ + return $this->toData('1', '数据不存在'); + } + if($info['status']!=0){ + return $this->toData('1', '数据已审核'); + } + + UserLoanModel::where($where)->update([ + 'status'=>intval($param['status']), + 'update_time'=>date('Y-m-d H:i:s') + ]); + + return $this->toData('0', 'SUCCESS', []); + } catch (\Exception $exception) { + return $this->toData('1', '系统繁忙', [$exception->getMessage()]); + } + } + // 获取用户验证码 public function getUserCode($param) diff --git a/app/admin/service/setting/ForexService.php b/app/admin/service/setting/ForexService.php index 1dfc4b44..5c5396e4 100644 --- a/app/admin/service/setting/ForexService.php +++ b/app/admin/service/setting/ForexService.php @@ -3,11 +3,14 @@ namespace app\admin\service\setting; use app\admin\service\AdminBaseService; +use app\admin\validate\setting\HqValidate; use app\home\service\BaseHomeService; use app\model\ContractListMode; use app\model\ContractSettingModel; use app\model\ContractTradeModel; use app\model\ForexListModel; +use app\model\ForexMarketModel; +use think\exception\ValidateException; use think\facade\Cache; class ForexService extends AdminBaseService @@ -267,4 +270,163 @@ class ForexService extends AdminBaseService } } + public function hq_index() + { + try { + $list = ForexMarketModel::where('type', 0)->order('id', 'desc')->select(); + $rows = []; + if(!$list->isEmpty()){ + $rows = $list->toArray(); + } + return $this->toData('0','SUCCSS',['list' => $rows, 'total' => count($rows)]); + }catch (\Exception $exception){ + return $this->toData('1', '系统繁忙', [$exception->getMessage()]); + } + } + + public function hq_add($param) + { + try { + // 参数校验 + validate(HqValidate::class)->scene('add')->check($param); + + // 已存在未执行的 不能再插入 + $count = ForexMarketModel::where('trade_name', $param['trade_name']) + ->where('is_get',1) + ->where('type', 0) + ->count(); + if($count > 0){ + return $this->toData('1','已存在未执行'); + } + + //判断 + $diff = strtotime($param['end_time']) - strtotime($param['begin_time']); + if($diff > 600 || $diff <=0){ + return $this->toData('1','时间无效-结束时间必须在开始时间十分钟以内'); + } + + // 不能有交叉时间 + $map1 = [ + ['trade_name', '=',$param['trade_name']], + ['begin_time','between', [$param['begin_time'], $param['end_time']]] + ]; + $map2 = [ + ['trade_name', '=',$param['trade_name']], + ['end_time','between', [$param['begin_time'], $param['end_time']]] + ]; + + $count = ForexMarketModel::whereOr([$map1,$map2]) + ->count(); + if($count > 0){ + return $this->toData('1','时间无效-时间不能有交叉'); + } + + $market = new ForexMarketModel; + $market->trade_name = $param['trade_name']; + $market->begin_time = $param['begin_time']; + $market->end_time = $param['end_time']; + $market->max_price = $param['max_price']; + $market->step = $param['step']; + $market->type = 0; + $market->save(); + + // 写入redis + $this->initForexHqData(); + + return $this->toData('0','SUCCESS'); + }catch (ValidateException $validateException){ + return $this->toData('1', $validateException->getMessage(), []); + }catch (\Exception $exception){ + return $this->toData('1', '系统繁忙', [$exception->getMessage()]); + } + } + + public function hq_edit($param) + { + try { + // 参数校验 + validate(HqValidate::class)->scene('edit')->check($param); + + // 已存在未执行的 不能再插入 + $count = ForexMarketModel::where('trade_name', $param['trade_name']) + ->where('id', '<>', $param['id']) + ->where('is_get',1) + ->where('type', 0) + ->count(); + + if($count > 0){ + return $this->toData('1','已存在未执行'); + } + + // 目标 + $market = ForexMarketModel::where('id', $param['id'])->where('type', 0)->find(); + if(empty($market)){ + return $this->toData('1','目标不存在'); + } + + //判断 + $diff = strtotime($param['end_time']) - strtotime($param['begin_time']); + if($diff > 600 || $diff <=0){ + return $this->toData('1','时间无效'); + } + + // 不能有交叉时间 + $map1 = [ + ['trade_name', '=',$param['trade_name']], + ['id', '<>',$param['id']], + ['begin_time','between', [$param['begin_time'], $param['end_time']]] + ]; + $map2 = [ + ['trade_name', '=',$param['trade_name']], + ['id', '<>',$param['id']], + ['end_time','between', [$param['begin_time'], $param['end_time']]] + ]; + + $count = ForexMarketModel::whereOr([$map1,$map2]) + ->count(); + if($count > 0){ + return $this->toData('1','时间无效'); + } + + $market->trade_name = $param['trade_name']; + $market->begin_time = $param['begin_time']; + $market->end_time = $param['end_time']; + $market->max_price = $param['max_price']; + $market->is_get = 1; + $market->step = $param['step']; + $market->save(); + + // redis + $this->initForexHqData(); + return $this->toData('0','SUCCESS'); + }catch (ValidateException $validateException){ + return $this->toData('1', $validateException->getMessage()); + }catch (\Exception $exception){ + return $this->toData('1', '系统繁忙', [$exception->getMessage(),$exception->getTrace()]); + } + } + + public function hq_del($param) + { + try { + // 参数校验 + validate(HqValidate::class)->scene('del')->check($param); + + // 目标 + $market = ForexMarketModel::where('id', $param['id'])->find(); + if(empty($market)){ + return $this->toData('1','目标不存在'); + } + + $market->delete(); + + $this->initForexHqData(); + return $this->toData('0','SUCCESS'); + }catch (ValidateException $validateException){ + return $this->toData('12', $validateException->getMessage(), []); + }catch (\Exception $exception){ + return $this->toData('11', '系统繁忙', [$exception->getMessage()]); + } + } + } \ No newline at end of file diff --git a/app/admin/service/setting/IPOService.php b/app/admin/service/setting/IPOService.php index 734133b1..0ef66d30 100644 --- a/app/admin/service/setting/IPOService.php +++ b/app/admin/service/setting/IPOService.php @@ -1609,6 +1609,21 @@ class IPOService extends AdminBaseService 'check' => 'jp_stock_', ]; break; + case 19: + $result = [ +// 'stock_table' => $prefix . 'pre_jp_stock', +// 'order_table' => $prefix . 'user_jp_pre_stock_order', + 'user_table' => $prefix . 'user_forex', + 'log_table' => $prefix . 'user_forex_log', + 'list_table' => $prefix . 'forex_list', + 'trade_table' => $prefix . 'forex_trade', +// 'give_order_table' => $prefix . 'user_jp_give_stock_order', + 'redis_key' => 'FOREX:STOCK:LIST:', + 'stock_id' => 'FOREX', +// 'country' => 'Japan', + 'check' => 'forex_stock_', + ]; + break; default: $result = []; break; diff --git a/app/home/job/SendEmail.php b/app/home/job/SendEmail.php index 36f60a5f..d422be75 100644 --- a/app/home/job/SendEmail.php +++ b/app/home/job/SendEmail.php @@ -16,7 +16,7 @@ class SendEmail */ public function fire(Job $job, $data) { - trace('新任务', 'info'); + trace('发送邮件任务开始', 'info'); $phpEmail = new \app\utility\SendEmail(); $success = false; for($times = 1; $times <= 3; $times++) { @@ -25,13 +25,11 @@ class SendEmail $success = true; break; } - - trace($job->getJobId().'---重试-----'.$times, 'info'); } // 任务失败 if (!$success) { - trace($job->getJobId().'---失败-------'.json_encode($data), 'info'); + trace($job->getJobId().'---发送邮件任务失败-------'.json_encode($data), 'info'); } // 删除任务 diff --git a/app/home/job/SendSms.php b/app/home/job/SendSms.php index b12c01dd..2daa9eb0 100644 --- a/app/home/job/SendSms.php +++ b/app/home/job/SendSms.php @@ -38,29 +38,17 @@ class SendSms */ public function fire(Job $job, $data) { - trace($job->getJobId().'---执行短信任务--------'.json_encode($data), 'info'); - - $config = $this->getConfig(); - if(empty($config)){ - trace('------- sms config empty -------', 'error'); - return; - } - - $key = "SMS:SEND:LAST_ACCESS_KEY"; - $lastUse = Cache::store('redis')->get($key); - $count = count($config); - if(empty($lastUse) || $lastUse >= ($count -1)){ - $nowKey = 0; - } else { - $nowKey = $lastUse++; - } + trace($job->getJobId().'---发送短信任务开始--------'.json_encode($data), 'info'); $to = $data['mobile']; $message = $data['subject']; - $accessKey = $config[$nowKey]['access_key']; - $secret = $config[$nowKey]['secret']; - Cache::store('redis')->set($key, $nowKey); - - (new \app\utility\SendSms())->send($to, $message, $accessKey, $secret); + $from = 'Bourse'; + $accessKey = env('SMS.ACCESS_KEY_ID'); + $secret = env('SMS.ACCESS_KEY_SECRET'); + if (empty($accessKey) || empty($secret)) { + trace('------- 短信账号配置错误 -------', 'error'); + return; + } + (new \app\utility\SendSms())->sendMessageToGlobe($to, $message, $from, $accessKey, $secret); // 删除任务 $job->delete(); } diff --git a/app/home/service/LoginService.php b/app/home/service/LoginService.php index 756b9999..647f07ed 100644 --- a/app/home/service/LoginService.php +++ b/app/home/service/LoginService.php @@ -2,24 +2,19 @@ namespace app\home\service; -use app\home\controller\User; use app\home\validate\LoginValidate; use app\model\AdminModel; use app\model\CountryModel; -use app\model\CustomerRelationalModel; -use app\model\EmailTemplateModel; use app\model\UserChatGroupModel; use app\model\UserChatLinkModel; use app\model\UserModel; use app\utility\Jwt; -use app\utility\SendSms; use app\utility\UnqId; use Psr\SimpleCache\InvalidArgumentException; use think\exception\ValidateException; use think\facade\Cache; use think\facade\Log; use think\facade\Queue; -use think\queue\Job; use GeoIp2\Database\Reader; class LoginService extends BaseHomeService @@ -97,10 +92,10 @@ class LoginService extends BaseHomeService // 获取客户端ip $ip = $this->getClientRealIp(); - $param['invite_code'] = $param['invite_code'] ?? ''; - $param['agent_code'] = $param['agent_code'] ?? ''; + $param['invite_code'] = $param['invite_code'] ?? ''; // 邀请码,可以是管理端的非代理账号,也可以是user表的用户 + $param['agent_code'] = $param['agent_code'] ?? ''; // 代理 $chCode = $param['ch_code'] ?? ''; // 注册渠道标识码 - $phone = $param['phone']; //p3定制需求-邮箱注册必须传手机号 + $phone = $param['phone']; //p2定制需求-邮箱注册必须传手机号 // 邮件注册参数校验 validate(LoginValidate::class)->scene('emailRegister')->check($param); @@ -231,31 +226,24 @@ class LoginService extends BaseHomeService // 如果有代理,绑定到代理下一个客服(轮询客服绑定) if ($agentId > 0 ) { $customerIds = AdminModel::getCustomerIdsByAgentId($agentId); // 获取代理下的所有客服ID - Log::info("邮箱注册 - 代理下客服ids=".json_encode($customerIds)); if (empty($customerIds)) { - return $this->toData('100400', 'There is no customer service account under the current agent', []); + return $this->toData('500', 'There is no customer service account under the current agent'); } - $counterKey = 'counter_bind_customer:'.$agentId; + $counterKey = 'counter_of_bind_customer:'.$agentId; $counterIndex = Cache::store('redis')->get($counterKey); //客服绑定计数器索引 if (empty($counterIndex)) { - $counterIndex = 0; - Cache::store('redis')->set($counterKey, $counterIndex); + Cache::store('redis')->set($counterKey, 1); $tagCustomerId = $customerIds[0]; } else { Cache::store('redis')->inc($counterKey); //更新计数器索引 $tagIndex = $counterIndex % count($customerIds); $tagCustomerId = $customerIds[$tagIndex]; } - Log::info("邮箱注册 - 要绑定的客服id=".$tagCustomerId); if ($tagCustomerId > 0) { - CustomerRelationalModel::create([ - 'user_id' => $userId, - 'customer_id' => $tagCustomerId, - 'agent_id' => $agentId, - ]); + $regUser->customer_id = $tagCustomerId; + $regUser->save(); } // 将注册账号的chat_id与绑定客服的chat_id加为好友 - Log::info("邮箱注册 - 获取去客服聊天账号信息, $tagCustomerId=".$tagCustomerId); $customerChatInfo = UserChatLinkModel::where(['user_id'=>$tagCustomerId, 'user_type'=>UserChatLinkModel::USER_CHAT_LINK_USER_TYPE_ADMIN])->find(); //查询客服的聊天账号uuid if (empty($customerChatInfo)) { return $this->toData('100400', 'The customer uuid is error.', []); @@ -577,13 +565,12 @@ class LoginService extends BaseHomeService if ($agentId > 0 ) { $customerIds = AdminModel::getCustomerIdsByAgentId($agentId); // 获取代理下的所有客服ID if (empty($customerIds)) { - return $this->toData('100400', 'There is no customer service account under the current agent', []); + return $this->toData('500', 'There is no customer service account under the current agent', []); } - $counterKey = 'counter_bind_customer:'.$agentId; + $counterKey = 'counter_of_bind_customer:'.$agentId; $counterIndex = Cache::store('redis')->get($counterKey); //客服绑定计数器索引 if (empty($counterIndex)) { - $counterIndex = 0; - Cache::store('redis')->set($counterKey, $counterIndex); + Cache::store('redis')->set($counterKey, 1); $tagCustomerId = $customerIds[0]; } else { Cache::store('redis')->inc($counterKey); //更新计数器索引 @@ -591,11 +578,8 @@ class LoginService extends BaseHomeService $tagCustomerId = $customerIds[$tagIndex]; } if ($tagCustomerId > 0) { - CustomerRelationalModel::create([ - 'user_id' => $userId, - 'customer_id' => $tagCustomerId, - 'agent_id' => $agentId, - ]); + $regUser->customer_id = $tagCustomerId; + $regUser->save(); } // 将注册账号的chat_id与绑定客服的chat_id加为好友 $customerChatInfo = UserChatLinkModel::where(['user_id'=>$tagCustomerId,'user_type'=>UserChatLinkModel::USER_CHAT_LINK_USER_TYPE_ADMIN])->find(); //查询客服的聊天账号uuid diff --git a/app/home/service/StockService.php b/app/home/service/StockService.php index 199a872f..46b3e3b8 100644 --- a/app/home/service/StockService.php +++ b/app/home/service/StockService.php @@ -79,15 +79,18 @@ class StockService extends BaseHomeService 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")) { + // p4项目无限制调用股票分析接口 + if (!isset($param['project']) || $param['project'] != 'p4') { + // 检测用户调用该接口次数,普通用户只能调用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次股票分析接口'); + } } } } diff --git a/app/home/service/UserService.php b/app/home/service/UserService.php index a1f18eaf..01fab44e 100644 --- a/app/home/service/UserService.php +++ b/app/home/service/UserService.php @@ -7,7 +7,6 @@ use app\model\ApiCalledNumModel; use app\model\AwsIvsModel; use app\model\AwsS3Model; use app\model\CountryModel; -use app\model\CustomerRelationalModel; use app\model\FileModel; use app\model\PurchaseVipLogModel; use app\model\PurchaseVipModel; @@ -143,7 +142,7 @@ class UserService extends BaseHomeService return $this->toData('100403', 'Please log in first', []); } - $info = UserModel::getFieldsByUserId('trade_password,lever_status,gender,last_name,first_name,real_status,country_id,user_no,nick_name,email,phone_number,country_code,agent_id,is_real,head_img_id,invite_code,is_test_user,customer_remark,label', $userId); + $info = UserModel::getFieldsByUserId('trade_password,lever_status,gender,last_name,first_name,real_status,country_id,user_no,nick_name,email,phone_number,country_code,agent_id,customer_id,is_real,head_img_id,invite_code,is_test_user,customer_remark,label', $userId); if (empty($info)) { return $this->toData('100400', 'The user does not exist.', []); } @@ -184,9 +183,8 @@ class UserService extends BaseHomeService // 查询用户绑定的客服chat_uuid $customerChatUuid = ""; $customerChatName = ""; - $customerRelationInfo = CustomerRelationalModel::where('user_id', $userId)->find(); //查询用户关联的客服账号信息 - if ($customerRelationInfo) { - $customerChatInfo = UserChatLinkModel::where(['user_id'=>$customerRelationInfo->customer_id, 'user_type'=>UserChatLinkModel::USER_CHAT_LINK_USER_TYPE_ADMIN])->find(); //查询客服的chat账号 + if (!empty($info['customer_id'])) { + $customerChatInfo = UserChatLinkModel::where(['user_id'=>$info['customer_id'], 'user_type'=>UserChatLinkModel::USER_CHAT_LINK_USER_TYPE_ADMIN])->find(); if ($customerChatInfo) { $customerChatUuid = $customerChatInfo->chat_uuid; $customerChatName = $customerChatInfo->chat_name; diff --git a/app/model/AdminModel.php b/app/model/AdminModel.php index b18dbf40..4f0ac0fd 100644 --- a/app/model/AdminModel.php +++ b/app/model/AdminModel.php @@ -82,6 +82,10 @@ class AdminModel extends BaseModel public static function getCustomerIdsByAgentId($agentId): array { - return self::where('parent_id', $agentId)->column('id'); + $role = AuthRoleModel::where(['name'=>'客服'])->find(); + if (empty($role)) { + return []; + } + return self::where(['role_id'=>$role->id,'parent_id'=>$agentId])->column('id'); } } \ No newline at end of file diff --git a/app/model/ForexMarketModel.php b/app/model/ForexMarketModel.php new file mode 100644 index 00000000..92231057 --- /dev/null +++ b/app/model/ForexMarketModel.php @@ -0,0 +1,11 @@ +