diff --git a/.gitignore b/.gitignore index 2485e885..f0b0c328 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,6 @@ /.vscode /vendor/ /runtime/ +*.log .env composer.lock \ No newline at end of file diff --git a/app/admin/controller/Admin.php b/app/admin/controller/Admin.php index 62199b4c..b9b22fc8 100644 --- a/app/admin/controller/Admin.php +++ b/app/admin/controller/Admin.php @@ -82,4 +82,25 @@ class Admin extends AdminBaseController $returnData = (new AdminService())->inviteCode(); return json($returnData); } + + // 获取翻译员列表 + public function getTranslatorList() + { + $returnData = (new AdminService())->getTranslatorList($this->request->param()); + return json($returnData); + } + + // 翻译员绑定客服 (翻译员添加客服聊天好友) + public function translatorAddCustomer() + { + $returnData = (new AdminService())->translatorAddCustomer($this->request->param()); + return json($returnData); + } + + // 翻译员绑定的客服列表 + public function translatorBindCustomerList() + { + $returnData = (new AdminService())->translatorBindCustomerList($this->request->param()); + return json($returnData); + } } diff --git a/app/admin/controller/Agent.php b/app/admin/controller/Agent.php index c6cf4ee4..8476937a 100644 --- a/app/admin/controller/Agent.php +++ b/app/admin/controller/Agent.php @@ -39,11 +39,19 @@ class Agent extends AdminBaseController return json($result); } - // 客服下所有注册用户 - public function customerUser() + // 客服下所有用户 + public function customerUserList() { $service = new AgentService(); - $result = $service->customerUser($this->request->param()); + $result = $service->customerUserList($this->request->param()); + return json($result); + } + + // 变更用户绑定客服 + public function changeUserCustomer() + { + $service = new AgentService(); + $result = $service->changeUserCustomer($this->request->param()); return json($result); } @@ -70,4 +78,18 @@ class Agent extends AdminBaseController $result = $service->awsIvsEdit($this->request->param()); return json($result); } + + public function userListByChannel() + { + $service = new AgentService(); + $result = $service->userListByChannel($this->request->param()); + return json($result); + } + + public function statsByChannel() + { + $service = new AgentService(); + $result = $service->statsByChannel($this->request->param()); + return json($result); + } } \ No newline at end of file diff --git a/app/admin/controller/Channel.php b/app/admin/controller/Channel.php new file mode 100644 index 00000000..d376bad2 --- /dev/null +++ b/app/admin/controller/Channel.php @@ -0,0 +1,50 @@ +list($this->request->param()); + return json($returnData); + } + + // 新增渠道 + public function add() + { + $returnData = (new ChannelService())->add($this->request->param()); + return json($returnData); + } + + // 编辑渠道 + public function edit() + { + $returnData = (new ChannelService())->edit($this->request->param()); + return json($returnData); + } + + // 删除渠道 + public function delete() + { + $returnData = (new ChannelService())->delete($this->request->param()); + return json($returnData); + } + + // 代理的渠道列表 + public function agentChannelList() + { + $returnData = (new ChannelService())->agentChannelList($this->request->param()); + return json($returnData); + } + + // 生成代理推广渠道 + public function createAgentChannel() + { + $returnData = (new ChannelService())->createAgentChannel($this->request->param()); + return json($returnData); + } +} \ No newline at end of file diff --git a/app/admin/controller/Test.php b/app/admin/controller/Test.php index cd6e45fe..3574e2cf 100644 --- a/app/admin/controller/Test.php +++ b/app/admin/controller/Test.php @@ -8,6 +8,13 @@ class Test extends AdminBaseController public function index() { - return json(['code' => '0', 'msg' => 'SUCCESS', 'data' => []]); + $memoryLimit = ini_get('memory_limit'); + $uploadMax = ini_get('upload_max_filesize'); + $postMax = ini_get('post_max_size'); + return json(['code' => '0', 'msg' => 'SUCCESS', 'data' => [ + 'memory_limit' => $memoryLimit, + 'upload_max' => $uploadMax, + 'post_max' => $postMax + ]]); } } \ No newline at end of file diff --git a/app/admin/controller/Upload.php b/app/admin/controller/Upload.php index 236deb4a..bf7cdccd 100644 --- a/app/admin/controller/Upload.php +++ b/app/admin/controller/Upload.php @@ -16,23 +16,52 @@ class Upload extends AdminBaseController try { // 获取文件 $file = $this->request->file('file'); - $param = $this->request->param(); - $rootPath = $param['path'] ?? ''; - $filename = $param['name'] ?? ''; - - // 将文件存储在本地 - $name = Filesystem::disk('local')->putFile($rootPath, $file); - $path = '/bs/image/' . $name; - - if (!empty($filename) && file_exists(app()->getRootPath() . 'public' . $path)) { - $newName = app()->getRootPath() . 'public/bs/' . $filename; - copy(app()->getRootPath() . 'public' . $path, $newName); - unlink(app()->getRootPath() . 'public' . $path); - $path = '/bs/' . $filename; + // 检测文件是否存在 + if (!$file) { + return json(['code' => 400, 'message' => 'No file uploaded']); + } + // 验证文件类型和大小 + $maxSize = 15 * 1024 * 1024; //限制M + if ($file->getSize() > $maxSize) { + return json(['code' => 400, 'message' => 'Upload file is too large']); + } + // 验证上传文件类型 + if (!in_array($file->getOriginalMime(), ['image/jpeg','image/png','image/webp','image/bm'])) { + return json(['code' => 400, 'message' => 'Upload file type error']); + } + // 生成唯一的文件名 + $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' => fopen($file->getRealPath(), 'r'), + 'ContentType' => $file->getOriginalMime(), // 设置文件的MIME, 不然s3会以流式存储 + ]); + if (empty($result) || empty($result['ObjectURL'])) { + return json(['code' => 400, 'message' => '上传s3失败']); } + // 记录上传的文件 + $resData = AwsS3Model::create([ + 'name' => $fileName, + 's3_url' => $result['ObjectURL'], + 'size' => $file->getSize(), + 'mime' => $file->getOriginalMime(), + 'ext' => $file->getOriginalExtension(), + ]); // 返回路径 - return json(['code' => '0', 'message' => '上传成功', 'data' => ['path' => $path]]); + return json(['code' => '0', 'message' => '上传成功', 'data' => ['path' => $resData->s3_url]]); } catch (\Exception $exception) { return json(['code' => '100500', 'message' => '系统繁忙', 'data' => [$exception->getMessage()]]); } @@ -54,7 +83,7 @@ class Upload extends AdminBaseController return json(['code' => 400, 'message' => 'The file size cannot exceed 1 GB']); } // 生成唯一的文件名 - $fileName = uniqid() . '.' . $file->getOriginalExtension(); + $fileName = bin2hex(random_bytes(16)) . '.' . $file->getOriginalExtension(); // 初始化s3客户端 $s3Config = Config::get('common.aws_s3'); $s3Client = new S3Client([ @@ -74,7 +103,9 @@ class Upload extends AdminBaseController 'ContentType' => $file->getOriginalMime(), // 设置文件的MIME, 不然s3会以流式存储 // 'ACL' => 'public-read', // 设置文件为公开可读 ]); - + if (empty($result) || empty($result['ObjectURL'])) { + return json(['code' => 400, 'message' => '上传s3失败']); + } // 记录上传的文件 $resData = AwsS3Model::create([ 'name' => $fileName, @@ -82,8 +113,7 @@ class Upload extends AdminBaseController 'size' => $file->getSize(), 'mime' => $file->getOriginalMime(), 'ext' => $file->getOriginalExtension(), - ]);; - + ]); // 返回上传成功的地址 return json(['code' => '0', 'message' => '上传成功', 'data' => [ 'id' => $resData->id, @@ -117,7 +147,7 @@ class Upload extends AdminBaseController return json(['code' => '100500', 'message' => '上传的文件类型不在允许范围内', 'data' => []]); } // 生成唯一的文件名 - $fileName = uniqid('video_', true); + $fileName = bin2hex(random_bytes(16)); // 初始化s3客户端 $s3Config = Config::get('common.aws_s3'); $s3Client = new S3Client([ diff --git a/app/admin/controller/User.php b/app/admin/controller/User.php index 024764fa..827beb82 100644 --- a/app/admin/controller/User.php +++ b/app/admin/controller/User.php @@ -123,4 +123,20 @@ class User extends AdminBaseController $result = $service->editLeverageNum($this->request->param()); return json($result); } + + // 编辑用户字段customer_remark + public function editCustomerRemark() + { + $service = new UserService(); + $result = $service->editCustomerRemark($this->request->param()); + return json($result); + } + + // 编辑用户标签字段 label + public function editUserLabel() + { + $service = new UserService(); + $result = $service->editUserLabel($this->request->param()); + return json($result); + } } diff --git a/app/admin/controller/Video.php b/app/admin/controller/Video.php index d088cf2e..cccea713 100644 --- a/app/admin/controller/Video.php +++ b/app/admin/controller/Video.php @@ -24,4 +24,33 @@ class Video extends AdminBaseController $returnData = (new VideoService())->editVideoOnDemand($this->request->param()); return json($returnData); } + + // 屏蔽词列表 + public function blockedWordList() + { + $returnData = (new VideoService())->blockedWordList($this->request->param()); + return json($returnData); + } + + // 新增屏蔽词 + public function blockedWordAdd() + { + $returnData = (new VideoService())->blockedWordAdd($this->request->param()); + return json($returnData); + } + + // 编辑屏蔽词 + public function blockedWordEdit() + { + $returnData = (new VideoService())->blockedWordEdit($this->request->param()); + return json($returnData); + } + + // 删除屏蔽词 + public function blockedWordDelete() + { + $returnData = (new VideoService())->blockedWordDelete($this->request->param()); + return json($returnData); + } + } \ No newline at end of file diff --git a/app/admin/route/app.php b/app/admin/route/app.php index eacef8b4..7e6e91d1 100644 --- a/app/admin/route/app.php +++ b/app/admin/route/app.php @@ -14,6 +14,7 @@ $header = [ //Route::get('/test', 'Test/index'); Route::post('/test', 'Test/index'); Route::post('/test_upload', 'Upload/uploadVideo'); +Route::post('test_api', 'Agent/statsByChannel'); Route::group('/', function () { // 上传图片 Route::post('/upload', 'Upload/upload'); @@ -23,6 +24,14 @@ Route::group('/', function () { Route::post('/set_config', 'Config/setConfig'); Route::post('/get_config', 'Config/getConfig'); + // 渠道列表 + Route::post('/channel/list', 'Channel/list'); //渠道列表 + Route::post('/channel/add', 'Channel/add'); //新增渠道 + Route::post('/channel/edit', 'Channel/edit'); //编辑渠道 + Route::post('/channel/delete', 'Channel/delete'); //删除渠道 + Route::post('/channel/agent_channel_list', 'Channel/agentChannelList'); //代理推广渠道列表 + Route::post('/channel/create_agent_channel', 'Channel/createAgentChannel'); //创建代理推广渠道 + // 视频点播相关 Route::post('/upload_video', 'Upload/uploadVideo'); //上传视频到aws s3 Route::post('/initiate_upload', 'Upload/initiateUpload'); //初始化分片上传 @@ -33,6 +42,11 @@ Route::group('/', function () { Route::post('/add_video', 'video/addVideoOnDemand'); //添加点播视频 Route::post('/edit_video', 'video/editVideoOnDemand'); //编辑点播视频 + Route::post('/video/blocked_word_list', 'Video/blockedWordList'); //屏蔽词列表 + Route::post('/video/blocked_word_add', 'Video/blockedWordAdd'); //添加屏蔽词 + Route::post('/video/blocked_word_edit', 'Video/blockedWordEdit'); //编辑屏蔽词 + Route::post('/video/blocked_word_delete', 'Video/blockedWordDelete'); //删除屏蔽词 + // 首页数据 Route::post('/index', 'Index/index'); Route::post('/read_num', 'Index/getReamNum'); @@ -160,10 +174,13 @@ 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/customerUser'); //获取客服下所有用户 + Route::post('/agent/customer_user_list', 'Agent/customerUserList'); //获取客服下所有用户 + Route::post('/agent/change_user_customer', 'Agent/changeUserCustomer'); //变更用户绑定的客服 Route::post('/agent/aws_ivs_list', 'Agent/awsIvsList'); //直播推流列表 Route::post('/agent/aws_ivs_add', 'Agent/awsIvsAdd'); //直播推流配置添加 Route::post('/agent/aws_ivs_edit', 'Agent/awsIvsEdit'); //直播推流配置编辑 + Route::post('/agent/user_list_by_channel', 'Agent/userListByChannel'); //代理下某个渠道的注册用户列表 + Route::post('agent/stats_by_channel', 'Agent/statsByChannel'); //按天统计用户数据 // 用户管理 Route::post('/user/index', 'User/index'); @@ -171,6 +188,8 @@ Route::group('/', function () { Route::post('/user/status', 'User/status'); Route::post('/user/change', 'User/change')->middleware('admin_log'); Route::post('/user/relation', 'User/relation'); + Route::post('/user/edit_customer_remark', 'User/editCustomerRemark'); //编辑用户字段 customer_remark + Route::post('/user/edit_user_label', 'User/editUserLabel'); //编辑用户标签字段 Route::post('/user/reg_phone', 'User/reg_phone')->middleware('admin_log'); Route::post('/user/reg_email', 'User/reg_email')->middleware('admin_log'); Route::post('/user/bank', 'User/bankDetail'); @@ -565,6 +584,9 @@ Route::group('/', function () { Route::get('/account/logout', 'Admin/logout'); Route::post('/account/update_account', 'Admin/updateAccount'); Route::get('/account/get_perm_code', 'Admin/getPermCode'); + Route::post('/account/get_translator_list', 'Admin/getTranslatorList'); //获取翻译员列表 + Route::post('/account/translator_add_customer', 'Admin/translatorAddCustomer'); //翻译员添加客服好友 + Route::post('/account/translator_bind_customer_list', 'Admin/translatorBindCustomerList'); // 翻译员绑定的客服列表 //权限菜单 Route::post('/auth/rule/add', 'auth.AuthRule/add'); diff --git a/app/admin/service/AdminBaseService.php b/app/admin/service/AdminBaseService.php index c6e76348..9670362d 100644 --- a/app/admin/service/AdminBaseService.php +++ b/app/admin/service/AdminBaseService.php @@ -239,8 +239,10 @@ class AdminBaseService 'create_time' => date('Y-m-d H:i:s'), 'update_time' => date('Y-m-d H:i:s') ]; - if (in_array($account_type, [1, 2, 8])) { + if (in_array($account_type, [2, 8,19])) { $insert_data['contract_id'] = $where['contract_id']; + } elseif ($account_type == 1) { + $insert_data['digital_id'] = $where['digital_id']; } else { $insert_data['stock_id'] = $where['stock_id']; diff --git a/app/admin/service/AdminService.php b/app/admin/service/AdminService.php index 762e5435..a3561b1d 100644 --- a/app/admin/service/AdminService.php +++ b/app/admin/service/AdminService.php @@ -7,6 +7,7 @@ use app\home\service\BaseHomeService; use app\model\AdminLogModel; use app\model\AdminModel; use app\model\AuthRoleModel; +use app\model\TranslatorCustomerModel; use app\model\UserChatGroupModel; use app\model\UserChatLinkModel; use phpDocumentor\Reflection\Type; @@ -33,45 +34,52 @@ class AdminService extends AdminBaseService } $param['password'] = (new UnqId())->encryptPassword($param['password'], env('ENCRYPT.ADMINSALT')); $param['invite_code'] = (new BaseHomeService())->getUniqInviteCode(); - $resAdmin = AdminModel::create($param); - - // 注册一下聊天账号 - $chatData = [ - 'Username' => $resAdmin->id."_".$resAdmin->user_name, //用account.id + account.user_name 拼接作为聊天账号注册的Username - 'Password' => '123456', - ]; - $chatUrl = env('CHAT_SERVER.BASE_URL') . '/api/user/register'; - $regChat = (new \app\utility\RequestChatServer())->ReqChatServer($chatUrl, $chatData); - if (!isset($regChat['data']['uuid'])) { - return $this->toData('0', '注册聊天账号失败.', ['chat_response' => $regChat]); - } - UserChatLinkModel::create([ - 'user_id' => $resAdmin->id, - 'user_type' => 2, - 'chat_uuid' => $regChat['data']['uuid'], - 'chat_name' => $regChat['data']['username'] - ]); - - // 创建聊天群 - $groupName = 'ivs-group'.$resAdmin->id; - $chatGroupData = [ - 'Name' => $groupName, - ]; - $chatGroupUrl = env('CHAT_SERVER.BASE_URL') . '/api/group/join/'.$regChat['data']['uuid']; - $chatGroupRes = (new \app\utility\RequestChatServer())->ReqChatServer($chatGroupUrl, $chatGroupData); - if (!isset($chatGroupRes['data']['group_uuid'])) { - return $this->toData('100400', 'Failed to register a chat group.', []); - } - UserChatGroupModel::create([ - 'user_id' => $resAdmin->id, - 'user_chat_uuid' => $regChat['data']['uuid'], - 'group_name' => $groupName, - 'group_uuid' => $chatGroupRes['data']['group_uuid'] - ]); - - - return $this->toData('0', '添加成功.', ['chatData' => $regChat]); + if (!$resAdmin) { + return $this->toData('1', '添加失败'); + } + // 检测一下是否注册过聊天账号,没有的话就注册一下聊天账号 + $isRegChat = UserChatLinkModel::where(['user_id'=>$resAdmin->id, 'user_type'=>UserChatLinkModel::USER_CHAT_LINK_USER_TYPE_ADMIN])->find(); + if (empty($isRegChat)) { + $chatData = [ + 'Username' => $resAdmin->id."_".$resAdmin->user_name, //用account.id + account.user_name 拼接作为聊天账号注册的Username + 'Password' => '123456', + 'Nickname' => $resAdmin->user_name, + 'Avatar' => env('USER.DEFAULT_HEAD_IMG_PATH'), + ]; + $chatUrl = env('CHAT_SERVER.BASE_URL') . '/api/user/register'; + $regChat = (new \app\utility\RequestChatServer())->ReqChatServer($chatUrl, $chatData); + if (!isset($regChat['data']['uuid'])) { + return $this->toData('0', '注册聊天账号失败.', ['chat_response' => $regChat]); + } + UserChatLinkModel::create([ + 'user_id' => $resAdmin->id, + 'user_type' => 2, + 'chat_uuid' => $regChat['data']['uuid'], + 'chat_name' => $regChat['data']['username'] + ]); + } + // 检测一下是否创建过聊天群组,没有的话创建一个 + $chatGroup = UserChatGroupModel::where(['user_id'=>$resAdmin->id,'remark'=>UserChatGroupModel::USER_CHAT_GROUP_REMARK_ADMIN_INIT])->find(); + if (empty($chatGroup)) { + $groupName = 'ivs-group'.$resAdmin->id; + $chatGroupData = [ + 'Name' => $groupName, + ]; + $chatGroupUrl = env('CHAT_SERVER.BASE_URL') . '/api/group/'.$regChat['data']['uuid']; + $chatGroupRes = (new \app\utility\RequestChatServer())->ReqChatServer($chatGroupUrl, $chatGroupData); + if (!isset($chatGroupRes['data']['group_uuid'])) { + return $this->toData('100400', '创建聊天群组失败'); + } + UserChatGroupModel::create([ + 'user_id' => $resAdmin->id, + 'user_chat_uuid' => $regChat['data']['uuid'], + 'group_name' => $groupName, + 'group_uuid' => $chatGroupRes['data']['group_uuid'], + 'remark' => UserChatGroupModel::USER_CHAT_GROUP_REMARK_ADMIN_INIT, + ]); + } + return $this->toData('0', '添加成功'); } catch (ValidateException $validateException) { $message = $validateException->getError(); return $this->toData('100400', $message); @@ -144,7 +152,7 @@ class AdminService extends AdminBaseService $infoArr = $info->toArray(); // 获取用户的聊天账号信息 - $chatInfo = UserChatLinkModel::where(['user_id'=>$userId, 'user_type'=>2])->find(); + $chatInfo = UserChatLinkModel::where(['user_id'=>$userId, 'user_type'=>UserChatLinkModel::USER_CHAT_LINK_USER_TYPE_ADMIN])->find(); $chat_uuid = 0; if (!empty($chatInfo)) { $chat_uuid = $chatInfo->chat_uuid; @@ -404,7 +412,111 @@ class AdminService extends AdminBaseService } } catch (\Exception $exception) { - return $this->toData('100500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]); + return $this->toData('500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]); + } + } + + // 获取翻译员列表 + public function getTranslatorList($param) + { + try { + if (empty($param['page']) || empty($param['limit'])) { + return $this->toData('400', '缺少分页参数'); + } + // 查询角色表中翻译角色的id + $role = AuthRoleModel::where(['name'=>'翻译'])->find(); + if (empty($role)) { + return $this->toData('400', '系统不存在翻译角色,请先创建'); + } + // 查询属于翻译角色的所有账号 + $where = ['role_id'=>$role->id]; + if (!empty($param['user_name'])) { + $list = AdminModel::where($where)->whereLike('user_name', '%'.$param['user_name'].'%')->order('id', 'desc')->paginate([ + 'list_rows' => $param['limit'], + 'page' => $param['page'], + ]); + } else { + $list = AdminModel::where($where)->order('id', 'desc')->paginate([ + 'list_rows' => $param['limit'], + 'page' => $param['page'], + ]); + } + + return $this->toData('0', 'SUCCESS', [ + 'list' => $list->items(), // 当前页的数据 + 'page' => $list->currentPage(), // 当前页码 + 'total' => $list->total(), // 总记录数 + 'last_page' => $list->lastPage(), // 最后一页页码 + ]); + } catch (\Exception $exception) { + return $this->toData('500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]); + } + } + + // 翻译员添加客服聊天好友 + public function translatorAddCustomer($param) + { + try { + if (empty($param['translator_id']) || empty($param['customer_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']]); + } + // 请求聊天服添加好友关系 + $translatorChatInfo = UserChatLinkModel::where(['user_id'=>$param['translator_id'], 'user_type'=>UserChatLinkModel::USER_CHAT_LINK_USER_TYPE_ADMIN])->find(); //查询翻译员的聊天账号uuid + 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]); + } catch (\Exception $exception) { + return $this->toData('500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]); + } + } + + // 翻译员以绑定的客服列表 + public function translatorBindCustomerList($param) + { + try { + if (empty($param['translator_id'])) { + return $this->toData('400', '缺少参数'); + } + if (empty($param['page']) || empty($param['limit'])) { + return $this->toData('400', '缺少分页参数'); + } + $list = TranslatorCustomerModel::where(['translator_id'=>$param['translator_id']])->order('id', 'desc')->paginate([ + 'list_rows' => $param['limit'], + 'page' => $param['page'], + ]); + return $this->toData('0', 'SUCCESS', [ + 'list' => $list->items(), // 当前页的数据 + 'page' => $list->currentPage(), // 当前页码 + 'total' => $list->total(), // 总记录数 + 'last_page' => $list->lastPage(), // 最后一页页码 + ]); + } catch (\Exception $exception) { + return $this->toData('500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]); } } diff --git a/app/admin/service/AgentService.php b/app/admin/service/AgentService.php index 7a6231d1..92d83f25 100644 --- a/app/admin/service/AgentService.php +++ b/app/admin/service/AgentService.php @@ -3,10 +3,19 @@ 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; +use app\model\StockJpTradeModel; +use app\model\StockTradeModel; +use app\model\UserChatLinkModel; use app\model\UserModel; +use app\model\UserWithdrawalModel; class AgentService extends AdminBaseService { @@ -72,27 +81,27 @@ class AgentService extends AdminBaseService { try { if (empty($param['id']) || !is_numeric($param['id'])) { - return $this->toData('1', '参错错误', ['list' => []]); + return $this->toData('400', '参错错误', ['list' => []]); } if (empty($param['agent_id']) || !is_numeric($param['agent_id'])) { - return $this->toData('1', '参错错误', ['list' => []]); + return $this->toData('400', '参错错误', ['list' => []]); } $user = UserModel::where('user_id', $param['id'])->find(); if (empty($user)) { - return $this->toData('1', '用户不存在', ['list' => []]); + return $this->toData('500', '用户不存在', ['list' => []]); } if ($user['parent_id'] != 0) { - return $this->toData('1', '只能绑定顶层用户', ['list' => []]); + return $this->toData('500', '只能绑定顶层用户', ['list' => []]); } // 判断代理是否有效 $admin = AdminModel::where('id', $param['agent_id'])->find(); $roleId = 10; if (empty($admin) || $admin['role_id'] != $roleId) { - return $this->toData('1', '代理不存在', ['list' => []]); + return $this->toData('500', '代理不存在', ['list' => []]); } // $agentUserId = env('AGENT.AGENT_GROUP_ID'); @@ -104,13 +113,13 @@ class AgentService extends AdminBaseService // 未绑定 直接绑定 if ($user->agent_id == 0) { UserModel::update(['agent_id' => $param['agent_id']], ['user_id' => $param['id']]); - return $this->toData('0', 'SUCCESS', []); + return $this->toData('0', 'success'); } // 取消绑定 if ($user->agent_id == $param['agent_id']) { UserModel::update(['agent_id' => 0], ['user_id' => $param['id']]); - return $this->toData('0', 'SUCCESS', []); + return $this->toData('0', 'success'); } return $this->toData('1', '该用户已被其他代理绑定, 请先取消绑定', []); @@ -124,33 +133,33 @@ class AgentService extends AdminBaseService { try { if (empty($param['agent_id']) || !is_numeric($param['agent_id'])) { - return $this->toData('1', '参错错误'); + return $this->toData('400', '参错错误'); } if (empty($param['user_id']) || !is_numeric($param['user_id'])) { - return $this->toData('1', '参错错误'); + return $this->toData('400', '参错错误'); } $user = UserModel::where('user_id', $param['user_id'])->find(); if (empty($user)) { - return $this->toData('1', '用户不存在'); + return $this->toData('400', '用户不存在'); } if ($user['parent_id'] != 0) { - return $this->toData('1', '只能绑定顶层用户'); + return $this->toData('400', '只能绑定顶层用户'); } // 判断代理是否有效 $admin = AdminModel::where('id', $param['agent_id'])->find(); $roleId = 10; if (empty($admin) || $admin['role_id'] != $roleId) { - return $this->toData('1', '代理不存在'); + return $this->toData('500', '代理不存在'); } UserModel::update(['agent_id' => $param['agent_id']], ['user_id' => $param['user_id']]); - return $this->toData('0', 'SUCCESS', []); + return $this->toData('0', 'success'); } catch (\Exception $exception) { - return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]); + return $this->toData('500', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]); } } @@ -158,12 +167,20 @@ class AgentService extends AdminBaseService { try { if (empty($param['page']) || !is_numeric($param['page'])) { - return $this->toData('1', '参错错误'); + return $this->toData('400', '参错错误'); + } + if (empty($param['limit']) || !is_numeric($param['limit'])) { + return $this->toData('400', '参错错误'); + } + + // 查询客服角色的ID + $customerRole = AuthRoleModel::where(['name'=>AuthRoleModel::NAME_CUSTOMER])->find(); + if (empty($customerRole)) { + return $this->toData('500', '系统中还没有客服角色'); } + $roleId = $customerRole->id; - // 角色ID - $roleId = 11; - // 代理ID + // 如有指定代理ID, 则查询代理ID下的客服列表,否则查询所有代理下的客服列表 $agentId = 0; if (isset($param['agent_id']) && is_numeric($param['agent_id'])) { $agentId = $param['agent_id']; @@ -173,11 +190,11 @@ class AgentService extends AdminBaseService }, function ($query) use($roleId) { $query->where('role_id', $roleId)->order('id', 'desc'); //查询所有客服列表 })->paginate([ - 'list_rows' => 15, // 每页显示 10 条 - 'page' => $param['page'], // 使用前端传递的页码 + 'list_rows' => $param['limit'], + 'page' => $param['page'], ]); - return $this->toData('0', 'SUCCESS', [ + return $this->toData('0', 'success', [ 'list' => $list->items(), // 当前页的数据 'page' => $list->currentPage(), // 当前页码 'total' => $list->total(), // 总记录数 @@ -185,22 +202,22 @@ class AgentService extends AdminBaseService 'agent_id' => $agentId, ]); } catch (\Exception $exception) { - return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]); + return $this->toData('500', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]); } } - public function customerUser($param) + public function customerUserList($param) { try { if (empty($param['customer_id']) || !is_numeric($param['customer_id'])) { - return $this->toData('1', '参错错误'); + return $this->toData('400', '参错错误'); } if (empty($param['page']) || !is_numeric($param['page'])) { - return $this->toData('1', '参错错误'); + return $this->toData('400', '参错错误'); } // 查询当前客服下的用户 $list = CustomerRelationalModel::where('customer_id', $param['customer_id'])->order('id', 'desc')->paginate([ - 'list_rows' => $param['limit'] ?? 15, + 'list_rows' => $param['limit'], 'page' => $param['page'], // 使用前端传递的页码 ]); $userIds = array_column($list->items(), 'user_id'); // 获取当前页的用户id @@ -210,7 +227,7 @@ class AgentService extends AdminBaseService $userDetails = UserModel::whereIn('user_id', $userIds)->select()->toArray(); } - return $this->toData('0', 'SUCCESS', [ + return $this->toData('0', 'success', [ 'list' => $list->items(), // 当前页的数据 'user_details' => $userDetails, 'page' => $list->currentPage(), // 当前页码 @@ -218,7 +235,51 @@ class AgentService extends AdminBaseService 'last_page' => $list->lastPage(), // 最后一页页码 ]); } catch (\Exception $exception) { - return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]); + return $this->toData('500', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]); + } + } + + public function changeUserCustomer($param) + { + try { + if (empty($param['user_id']) || empty($param['old_customer_id']) || empty($param['new_customer_id'])) { + 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', '操作的数据不存在'); + } + // 变更的客服必须是同一个代理 + $newCustomer = AdminModel::where(['id'=>$param['new_customer_id']])->find(); + if (empty($newCustomer)) { + return $this->toData('500', '要变更的客服不存在'); + } + if ($newCustomer->parent_id != $cstRlt->agent_id) { + return $this->toData('500', '新客服不属于同一个代理'); + } + // 变更客服绑定关系 + $cstRlt->customer_id = $param['new_customer_id']; + $cstRlt->save(); + + // 将用户与新客服的聊天账号加好友 + $userChatInfo = UserChatLinkModel::where(['user_id'=>$param['user_id'], 'user_type'=>UserChatLinkModel::USER_CHAT_LINK_USER_TYPE_PC])->find(); + if (empty($userChatInfo)) { + return $this->toData('500', '用户的聊天数据错误'); + } + $customerChatInfo = UserChatLinkModel::where(['user_id'=>$param['new_customer_id'], 'user_type'=>UserChatLinkModel::USER_CHAT_LINK_USER_TYPE_ADMIN])->find(); + if (empty($customerChatInfo)) { + return $this->toData('500', '客服的聊天数据错误'); + } + $chatFriendsData = [ + 'UserUuid' => $userChatInfo->chat_uuid, + 'CustomerUuid' => $customerChatInfo->chat_uuid, + ]; + $chatFriendsUrl = env('CHAT_SERVER.BASE_URL') . '/api/eachOtherFriends'; + $chatFriendsRes = (new \app\utility\RequestChatServer())->ReqChatServer($chatFriendsUrl, $chatFriendsData); + return $this->toData('0', 'success', $chatFriendsRes); + } catch (\Exception $exception) { + return $this->toData('500', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]); } } @@ -226,29 +287,32 @@ class AgentService extends AdminBaseService { try { if (empty($param['page']) || !is_numeric($param['page'])) { - return $this->toData('1', '参错错误'); + return $this->toData('400', '参错错误'); + } + if (empty($param['limit']) || !is_numeric($param['limit'])) { + return $this->toData('400', '参错错误'); } if (isset($param['title'])) { $list = AwsIvsModel::where('title', $param['title'])->order('id', 'desc')->paginate([ - 'list_rows' => 15, + 'list_rows' => $param['limit'], 'page' => $param['page'], ]); } else { $list = AwsIvsModel::order('id', 'desc')->paginate([ - 'list_rows' => 15, + 'list_rows' => $param['limit'], 'page' => $param['page'], ]); } - return $this->toData('0', 'SUCCESS', [ + return $this->toData('0', 'success', [ 'list' => $list->items(), // 当前页的数据 'page' => $list->currentPage(), // 当前页码 'total' => $list->total(), // 总记录数 'last_page' => $list->lastPage(), // 最后一页页码 ]); } catch (\Exception $exception) { - return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]); + return $this->toData('500', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]); } } @@ -256,30 +320,30 @@ class AgentService extends AdminBaseService { try { if (empty($param['title'])) { - return $this->toData('1', 'Missing param title'); + return $this->toData('400', 'Missing param title'); } if (empty($param['anchor_name'])) { - return $this->toData('1', 'Missing param anchor_name'); + return $this->toData('400', 'Missing param anchor_name'); } if (empty($param['desc'])) { - return $this->toData('1', 'Missing param desc'); + return $this->toData('400', 'Missing param desc'); } if (empty($param['push_url'])) { - return $this->toData('1', 'Missing param push_url'); + return $this->toData('400', 'Missing param push_url'); } if (empty($param['secret_key'])) { - return $this->toData('1', 'Missing param secret_key'); + return $this->toData('400', 'Missing param secret_key'); } if (empty($param['play_url'])) { - return $this->toData('1', 'Missing param play_url'); + return $this->toData('400', 'Missing param play_url'); } if (empty($param['agent_id'])) { - return $this->toData('1', 'Missing 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('1', '一个代理下只能配置一个推流信息'); + return $this->toData('500', '一个代理下只能配置一个推流信息'); } //保存推流配置 $res = AwsIvsModel::create([ @@ -292,9 +356,9 @@ class AgentService extends AdminBaseService 'play_url' => $param['play_url'], 'agent_id' => $param['agent_id'] ]); - return $this->toData('0', 'SUCCESS', ['id' => $res->id]); + return $this->toData('0', 'success', ['id' => $res->id]); } catch (\Exception $exception) { - return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]); + return $this->toData('500', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]); } } @@ -302,15 +366,15 @@ class AgentService extends AdminBaseService { try { if (empty($param['id'])) { - return $this->toData('1', 'Missing param id'); + return $this->toData('400', 'Missing param id'); } if (empty($param['title']) || empty($param['anchor_name']) || empty($param['desc']) || empty($param['push_url']) || empty($param['secret_key']) || empty($param['play_url']) || empty($param['agent_id'])) { - return $this->toData('1', 'Parameter error'); + return $this->toData('400', 'Parameter error'); } // 检查是否存在数据 $ckInfo = AwsIvsModel::where('id', $param['id'])->find(); if (empty($ckInfo)) { - return $this->toData('1', '编辑的数据不存在'); + return $this->toData('500', '编辑的数据不存在'); } $ckInfo->title = $param['title']; $ckInfo->anchor_name = $param['anchor_name']; @@ -320,9 +384,166 @@ class AgentService extends AdminBaseService $ckInfo->secret_key = $param['secret_key']; $ckInfo->play_url = $param['play_url']; $ckInfo->save(); - return $this->toData('1', 'Successful'); + return $this->toData('0', 'success'); } catch (\Exception $exception) { - return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]); + return $this->toData('500', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]); + } + } + + // 代理下每个渠道的用户注册列表 + public function userListByChannel($param) + { + try { + if (empty($param['agent_channel_id']) || empty($param['page']) || empty($param['limit'])) { + return $this->toData('400', '参数错误'); + } + // 检测是否存在目标代理渠道 + $agentChannel = AgentChannelListModel::where(['id'=>$param['agent_channel_id']])->find(); + if (empty($agentChannel)) { + return $this->toData('500', '代理渠道数据为空'); + } + // 查询该代理渠道下的用户数据 + $list = UserModel::where(['ch_code'=>$agentChannel->ch_code])->order('user_id', 'desc')->paginate([ + 'list_rows' => $param['limit'], + 'page' => $param['page'], + ]); + if (empty($list->items())) { + return $this->toData('0', 'success', [ + 'list' => $list->items(), // 当前页的数据 + 'page' => $list->currentPage(), // 当前页码 + 'total' => $list->total(), // 总记录数 + 'last_page' => $list->lastPage(), // 最后一页页码 + ]); + } + + // 获取所有用户ID + $userIdArr = array_column($list->items(), 'user_id'); + // 获取用户是否会员VIP + $userVipList = PurchaseVipModel::where('user_id', 'in', $userIdArr)->column('expire,created_at', 'user_id'); + + $resArr = []; + foreach ($list->items() as $v) { + $resArr[] = [ + 'user_id' => $v['user_id'], + 'user_no' => $v['user_no'], + 'nick_name' => $v['nick_name'], + 'email' => $v['email'], + 'phone_number' => $v['phone_number'], + 'parent_id' => $v['parent_id'], + 'origin_user_id' => $v['origin_user_id'], + 'agent_id' => $v['agent_id'], + 'is_real' => $v['is_real'], + 'real_status' => $v['real_status'], + 'head_img_id' => $v['head_img_id'], + 'last_login_time' => $v['last_login_time'], + 'customer_remark' => $v['customer_remark'], + 'label' => $v['label'], + 'ch_code' => $v['ch_code'], + 'create_time' => $v['create_time'], + 'is_vip' => isset($userVipList[$v['user_id']]) ?? '', + 'vip_expire' => $userVipList[$v['user_id']]['expire'] ?? '', + 'vip_created' => $userVipList[$v['user_id']]['created_at'] ?? '', + ]; + } + + + return $this->toData('0', 'success', [ + 'list' => $resArr, + 'page' => $list->currentPage(), // 当前页码 + 'total' => $list->total(), // 总记录数 + 'last_page' => $list->lastPage(), // 最后一页页码 + ]); + } catch (\Exception $exception) { + return $this->toData('500', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]); + } + } + + // 按天统计每个渠道下的数据 + public function statsByChannel($param) + { + try { + if (empty($param['ch_code'])) { + return $this->toData('400', '参数错误'); + } + if (empty($param['day'])) { + return $this->toData('400', '参数错误'); + } + + // 注册数 + $userStats = UserModel::whereDay('create_time', $param['day'])->where(['ch_code'=>$param['ch_code']])->select()->toArray(); + $regCount = count($userStats); + $userIds = array_column($userStats, 'user_id'); + if (empty($userIds)) { + return $this->toData('0', 'success', [ + 'reg_count' => $regCount, + 'recharge_count' => 0, + 'recharge_amount' => 0, + 'withdraw_count' => 0, + 'withdraw_amount' => 0, + 'stock_count' => 0, //美股交易笔数 + 'stock_in_amount' => 0, //美股交易买入总金额 + 'stock_out_amount' => 0, //美股交易卖出总金额 + 'stock_diff_amount' => 0, //美股买入与卖出差 + 'stock_jp_count' => 0, //日股 + 'stock_jp_in_amount' => 0, + 'stock_jp_out_amount' => 0, + 'stock_jp_diff_amount' => 0, + 'stock_forex_count' => 0, // 大宗外汇 + 'stock_forex_in_amount' => 0, + 'stock_forex_out_amount' => 0, + 'stock_forex_diff_amount' => 0, + ]); + } + + // 充值数 - 充值笔数、充值金额、 + $rechargeCount = RechargeApplyModel::whereDay('create_time', $param['day'])->whereIn('user_id', $userIds)->count(); + $rechargeAmount = RechargeApplyModel::whereDay('create_time', $param['day'])->whereIn('user_id', $userIds)->sum('recharge_num'); + + // 提款数 - 提现笔数、提现金额 + $withdrawCount = UserWithdrawalModel::whereDay('create_time', $param['day'])->whereIn('user_id', $userIds)->count(); + $withdrawAmount = UserWithdrawalModel::whereDay('create_time', $param['day'])->whereIn('user_id', $userIds)->sum('apply_num'); + + // 美股交易数 - 交易笔数、交易总盈亏 + $stockCount = StockTradeModel::whereDay('create_time', $param['day'])->whereIn('user_id', $userIds)->count(); + $stockInAmount = StockTradeModel::whereDay('create_time', $param['day'])->whereIn('user_id', $userIds)->where('trade_type', 1)->sum('order_money'); // 买入总金额 + $stockOutAmount = StockTradeModel::whereDay('create_time', $param['day'])->whereIn('user_id', $userIds)->where('trade_type', 2)->sum('order_money'); // 卖出总金额 + $stockDiffAmount = $stockInAmount - $stockOutAmount; + + // 日股交易数 - 交易笔数、交易总盈亏 + $stockJpCount = StockJpTradeModel::whereDay('create_time', $param['day'])->whereIn('user_id', $userIds)->count(); + $stockJpInAmount = StockJpTradeModel::whereDay('create_time', $param['day'])->whereIn('user_id', $userIds)->where('trade_type', 1)->sum('order_money'); // 买入总金额 + $stockJpOutAmount = StockJpTradeModel::whereDay('create_time', $param['day'])->whereIn('user_id', $userIds)->where('trade_type', 2)->sum('order_money'); // 卖出总金额 + $stockJpDiffAmount = $stockJpInAmount - $stockJpOutAmount; + + // 大宗(外汇)交易数据 - 交易笔数、交易总金额 + $stockForexCount = ForexTradeModel::whereDay('create_time', $param['day'])->whereIn('user_id', $userIds)->count(); + $stockForexInAmount = ForexTradeModel::whereDay('create_time', $param['day'])->whereIn('user_id', $userIds)->where('trade_type', 1)->sum('order_money'); // 买入总金额 + $stockForexOutAmount = ForexTradeModel::whereDay('create_time', $param['day'])->whereIn('user_id', $userIds)->where('trade_type', 2)->sum('order_money'); // 卖出总金额 + $stockForexDiffAmount = $stockForexInAmount - $stockForexOutAmount; + + // 交易数 - 交易笔数、交易总数盈亏 + return $this->toData('0', 'success', [ + 'reg_count' => $regCount, + 'recharge_count' => $rechargeCount, + 'recharge_amount' => $rechargeAmount, + 'withdraw_count' => $withdrawCount, + 'withdraw_amount' => $withdrawAmount, + 'stock_count' => $stockCount, //美股交易总笔数 + 'stock_in_amount' => $stockInAmount, //美股交易买入总金额 + 'stock_out_amount' => $stockOutAmount, //美股交易卖出总金额 + 'stock_diff_amount' => $stockDiffAmount, //美股买入与卖出差 + 'stock_jp_count' => $stockJpCount, //日股 + 'stock_jp_in_amount' => $stockJpInAmount, + 'stock_jp_out_amount' => $stockJpOutAmount, + 'stock_jp_diff_amount' => $stockJpDiffAmount, + 'stock_forex_count' => $stockForexCount, // 大宗外汇 + 'stock_forex_in_amount' => $stockForexInAmount, + 'stock_forex_out_amount' => $stockForexOutAmount, + 'stock_forex_diff_amount' => $stockForexDiffAmount, + ]); + } catch (\Exception $exception) { + return $this->toData('500', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]); } } + } \ No newline at end of file diff --git a/app/admin/service/ChannelService.php b/app/admin/service/ChannelService.php new file mode 100644 index 00000000..3732b81d --- /dev/null +++ b/app/admin/service/ChannelService.php @@ -0,0 +1,128 @@ +scene('list')->check($param); + $where = ['state'=>1]; + $list = ChannelListModel::where($where)->order('id', 'desc')->paginate([ + 'list_rows' => $param['limit'], + 'page' => $param['page'], + ]); + return $this->toData('0', 'SUCCESS', [ + 'list' => $list->items(), // 当前页的数据 + 'page' => $list->currentPage(), // 当前页码 + 'total' => $list->total(), // 总记录数 + 'last_page' => $list->lastPage(), // 最后一页页码 + ]); + } catch (\Exception $exception) { + return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]); + } + } + + public function add($param) + { + try { + validate(ChannelValidate::class)->scene('add')->check($param); + // 检测是否存在相同渠道 + $exists = ChannelListModel::where('channel', $param['channel'])->find(); + if ($exists) { + return json(['code'=>1, 'message'=>'已存在相同渠道,请勿重复添加']); + } + // 插入新增渠道 + $desc = $param['desc'] ?? ""; + ChannelListModel::create(['channel'=>$param['channel'], 'desc'=>$desc, 'state' => 1]); + return $this->toData('0', 'success'); + } catch (\Exception $exception) { + return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]); + } + } + + public function edit($param) + { + try { + validate(ChannelValidate::class)->scene('edit')->check($param); + $channel = ChannelListModel::where(['id'=>$param['id']])->find(); + if (empty($channel)) { + return json(['code'=>1, 'message'=>'操作的数据不存在']); + } + $channel->channel = $param['channel']; + $channel->desc = $param['desc'] ?? ''; + $channel->save(); + return $this->toData('0', 'success'); + } catch (\Exception $exception) { + return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]); + } + } + + public function delete($param) + { + try { + validate(ChannelValidate::class)->scene('delete')->check($param); + $channel = ChannelListModel::where(['id'=>$param['id']])->find(); + if (empty($channel)) { + return json(['code'=>1, 'message'=>'操作的数据不存在']); + } + $channel->state = 0; + $channel->save(); + return $this->toData('0', 'success'); + } catch (\Exception $exception) { + return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]); + } + } + + public function agentChannelList($param) + { + try { + validate(ChannelValidate::class)->scene('agent_channel_list')->check($param); + $where = []; + if (!empty($param['agent_id'])) { + $where['agent_id'] = $param['agent_id']; + } + $list = AgentChannelListModel::where($where)->order('id', 'desc')->paginate([ + 'list_rows' => $param['limit'], + 'page' => $param['page'], + ]); + return $this->toData('0', 'SUCCESS', [ + 'list' => $list->items(), // 当前页的数据 + 'page' => $list->currentPage(), // 当前页码 + 'total' => $list->total(), // 总记录数 + 'last_page' => $list->lastPage(), // 最后一页页码 + ]); + } catch (\Exception $exception) { + return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]); + } + } + + public function createAgentChannel($param) + { + try { + validate(ChannelValidate::class)->scene('agent_created_channel')->check($param); + // 代理推广连接 = 落地页域名 + 代理ID + 渠道名称 + if (empty($param['domain'])) { + return $this->toData('1', '缺少参数domain'); + } + $uqCode = bin2hex(random_bytes(16)); + $domain = rtrim($param['domain'], '/') . '/'; + $channelAddr = $domain.'?ext='.$uqCode; + // 检测是否存在相同渠道 + $exists = AgentChannelListModel::where(['agent_id'=>$param['agent_id'], 'channel_addr'=>$channelAddr])->find(); + if ($exists) { + return json(['code'=>1, 'message'=>'该代理已存在相同渠道']); + } + // 插入新增渠道 + AgentChannelListModel::create(['agent_id'=>$param['agent_id'], 'channel_addr'=>$channelAddr, 'channel'=>$param['channel'], 'ch_code'=>$uqCode]); + return $this->toData('0', 'success'); + } catch (\Exception $exception) { + return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]); + } + } + +} \ No newline at end of file diff --git a/app/admin/service/OrderService.php b/app/admin/service/OrderService.php index 8a91f7cb..f0a048d4 100644 --- a/app/admin/service/OrderService.php +++ b/app/admin/service/OrderService.php @@ -137,8 +137,12 @@ class OrderService extends AdminBaseService } } + $totalMoney = 0; + if ($totalModel['total']) { + $totalMoney = round($totalModel['total'], 4); + } return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, - 'extent' => ['totalMoney' => round($totalModel['total'], 4), + 'extent' => ['totalMoney' => $totalMoney, ]]); } catch (ValidateException $validateException) { @@ -230,8 +234,12 @@ class OrderService extends AdminBaseService } } + $totalMoney = 0; + if ($totalModel['total']) { + $totalMoney = round($totalModel['total'], 4); + } return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, - 'extent' => ['totalMoney' => round($totalModel['total'], 4), + 'extent' => ['totalMoney' => $totalMoney, ]]); } catch (ValidateException $validateException) { @@ -323,8 +331,12 @@ class OrderService extends AdminBaseService } } + $totalMoney = 0; + if ($totalModel['total']) { + $totalMoney = round($totalModel['total'], 4); + } return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, - 'extent' => ['totalMoney' => round($totalModel['total'], 4), + 'extent' => ['totalMoney' => $totalMoney, ]]); } catch (ValidateException $validateException) { @@ -425,8 +437,12 @@ class OrderService extends AdminBaseService } } + $totalMoney = 0; + if ($totalModel['total']) { + $totalMoney = round($totalModel['total'], 4); + } return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, - 'extent' => ['totalMoney' => round($totalModel['total'], 4), 'totalServiceCost' => $totalServiceCost, + 'extent' => ['totalMoney' => $totalMoney, 'totalServiceCost' => $totalServiceCost, ]]); } catch (ValidateException $validateException) { @@ -517,8 +533,12 @@ class OrderService extends AdminBaseService } } + $totalMoney = 0; + if ($totalModel['total']) { + $totalMoney = round($totalModel['total'], 4); + } return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, - 'extent' => ['totalMoney' => round($totalModel['total'], 4), + 'extent' => ['totalMoney' => $totalMoney, ]]); } catch (ValidateException $validateException) { @@ -610,8 +630,12 @@ class OrderService extends AdminBaseService } } + $totalMoney = 0; + if ($totalModel['total']) { + $totalMoney = round($totalModel['total'], 4); + } return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, - 'extent' => ['totalMoney' => round($totalModel['total'], 4), + 'extent' => ['totalMoney' => $totalMoney, ]]); } catch (ValidateException $validateException) { @@ -826,8 +850,12 @@ class OrderService extends AdminBaseService } } + $totalMoney = 0; + if ($totalModel['total']) { + $totalMoney = round($totalModel['total'], 4); + } return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, - 'extent' => ['totalMoney' => round($totalModel['total'], 4), 'totalServiceCost' => $totalServiceCost, + 'extent' => ['totalMoney' => $totalMoney, 'totalServiceCost' => $totalServiceCost, ]]); } catch (ValidateException $validateException) { @@ -918,8 +946,12 @@ class OrderService extends AdminBaseService } } + $totalMoney = 0; + if ($totalModel['total']) { + $totalMoney = round($totalModel['total'], 4); + } return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, - 'extent' => ['totalMoney' => round($totalModel['total'], 4), + 'extent' => ['totalMoney' => $totalMoney, ]]); } catch (ValidateException $validateException) { @@ -1011,8 +1043,12 @@ class OrderService extends AdminBaseService } } + $totalMoney = 0; + if ($totalModel['total']) { + $totalMoney = round($totalModel['total'], 4); + } return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, - 'extent' => ['totalMoney' => round($totalModel['total'], 4), + 'extent' => ['totalMoney' => $totalMoney, ]]); } catch (ValidateException $validateException) { @@ -1227,8 +1263,12 @@ class OrderService extends AdminBaseService } } + $totalMoney = 0; + if ($totalModel['total']) { + $totalMoney = round($totalModel['total'], 4); + } return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, - 'extent' => ['totalMoney' => round($totalModel['total'], 4), 'totalServiceCost' => $totalServiceCost, + 'extent' => ['totalMoney' => $totalMoney, 'totalServiceCost' => $totalServiceCost, ]]); } catch (ValidateException $validateException) { @@ -1319,8 +1359,12 @@ class OrderService extends AdminBaseService } } + $totalMoney = 0; + if ($totalModel['total']) { + $totalMoney = round($totalModel['total'], 4); + } return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, - 'extent' => ['totalMoney' => round($totalModel['total'], 4), + 'extent' => ['totalMoney' => $totalMoney, ]]); } catch (ValidateException $validateException) { @@ -1412,8 +1456,12 @@ class OrderService extends AdminBaseService } } + $totalMoney = 0; + if ($totalModel['total']) { + $totalMoney = round($totalModel['total'], 4); + } return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, - 'extent' => ['totalMoney' => round($totalModel['total'], 4), + 'extent' => ['totalMoney' => $totalMoney, ]]); } catch (ValidateException $validateException) { @@ -1637,10 +1685,15 @@ class OrderService extends AdminBaseService } } + $totalMoney = 0; + if ($totalModel['total']) { + $totalMoney = round($totalModel['total'], 4); + } return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, - 'extent' => ['totalMoney' => round($totalModel['total'], 4), 'totalServiceCost' => $totalServiceCost, + 'extent' => ['totalMoney' => $totalMoney, 'totalServiceCost' => $totalServiceCost, ]]); + } catch (ValidateException $validateException) { // 参数校验失败 $message = $validateException->getError(); @@ -1742,8 +1795,12 @@ class OrderService extends AdminBaseService } } + $totalMoney = 0; + if ($totalModel['total']) { + $totalMoney = round($totalModel['total'], 4); + } return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, - 'extent' => ['totalMoney' => round($totalModel['total'], 4), + 'extent' => ['totalMoney' => $totalMoney, ]]); } catch (ValidateException $validateException) { @@ -1846,8 +1903,12 @@ class OrderService extends AdminBaseService } } + $totalMoney = 0; + if ($totalModel['total']) { + $totalMoney = round($totalModel['total'], 4); + } return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, - 'extent' => ['totalMoney' => round($totalModel['total'], 4), + 'extent' => ['totalMoney' => $totalMoney, ]]); } catch (ValidateException $validateException) { @@ -2489,8 +2550,12 @@ class OrderService extends AdminBaseService } } + $totalMoney = 0; + if ($totalModel['total']) { + $totalMoney = round($totalModel['total'], 4); + } return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, - 'extent' => ['totalMoney' => round($totalModel['total'], 4), 'totalServiceCost' => $totalServiceCost, + 'extent' => ['totalMoney' => $totalMoney, 'totalServiceCost' => $totalServiceCost, ]]); } catch (ValidateException $validateException) { @@ -2589,9 +2654,12 @@ class OrderService extends AdminBaseService } } + $totalMoney = 0; + if ($totalModel['total']) { + $totalMoney = round($totalModel['total'], 4); + } return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, - 'extent' => ['totalMoney' => round($totalModel['total'], 4), - ]]); + 'extent' => ['totalMoney' => $totalMoney]]); } catch (ValidateException $validateException) { // 参数校验失败 @@ -2690,8 +2758,12 @@ class OrderService extends AdminBaseService } } + $totalMoney = 0; + if ($totalModel['total']) { + $totalMoney = round($totalModel['total'], 4); + } return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, - 'extent' => ['totalMoney' => round($totalModel['total'], 4), + 'extent' => ['totalMoney' => $totalMoney, ]]); } catch (ValidateException $validateException) { diff --git a/app/admin/service/UserService.php b/app/admin/service/UserService.php index 0bd452a3..bbfc356a 100644 --- a/app/admin/service/UserService.php +++ b/app/admin/service/UserService.php @@ -5,10 +5,13 @@ namespace app\admin\service; use app\admin\validate\UserValidate; use app\home\service\BaseHomeService; use app\model\AdminModel; +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; use app\model\UserContractModel; use app\model\UserContractSecModel; use app\model\UserDigitalModel; @@ -33,6 +36,7 @@ use app\model\UserStockFundModel; use think\exception\ValidateException; use app\utility\UnqId; use think\facade\Cache; +use think\facade\Log; class UserService extends AdminBaseService { @@ -205,6 +209,14 @@ 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) { + $customerIds = array_values($customerRelationList); + $customerNames = AdminModel::where('id', 'in', $customerIds)->column('nick_name', 'id'); + } //最近登录IP、最近登录国家 $subQuery = UserLoginLog::field('user_id,MAX(login_date) AS last_login_date') @@ -213,6 +225,12 @@ class UserService extends AdminBaseService ->join([$subQuery => 'w'], 'a.user_id=w.user_id AND a.login_date=w.last_login_date')->column(['id', 'ip', 'country', 'city'], 'a.user_id'); foreach ($userList as $item) { + $itmCustomerId = $customerRelationList[$item['user_id']] ?? 0; //当前用户关联的客服ID + $itmCustomerName = ""; + if ($itmCustomerId) { + $itmCustomerName = $customerNames[$itmCustomerId] ?? ""; //当前客服的名称 + } + $rows[] = [ 'id' => $item['user_id'], 'user_no' => $item['user_no'], @@ -223,6 +241,10 @@ class UserService extends AdminBaseService 'invite_code' => $item['invite_code'], 'email' => $item['email'], 'mobile' => $item['country_code'] . '-' . $item['phone_number'], + 'customer_remark' => $item['customer_remark'], + 'label' => $item['label'], + 'customer_id' => $itmCustomerId, + 'customer_name' => $itmCustomerName, //余额 'digital' => $userDigitalList[$item['user_id']]['usable_num'] ?? '0', @@ -360,12 +382,10 @@ class UserService extends AdminBaseService switch ($param['type']) { case '1': //现货 $originMoney = UserDigitalModel::where('user_id', $param['id'])->value('usable_num'); - $rate = 1; break; case '2': //合约 $originMoney = UserContractModel::where('user_id', $param['id'])->value('usable_num'); - $rate = 1; break; case '3': //美股 @@ -391,40 +411,34 @@ class UserService extends AdminBaseService $originMoney = UserStockIdnModel::where('user_id', $param['id']) ->where('stock_id', 'IDR') ->value('usable_num'); - $rate = $marketArr['IDR'] ?? 0; break; case '5': $originMoney = UserStockMysModel::where('user_id', $param['id']) ->where('stock_id', 'MYR') ->value('usable_num'); - $rate = $marketArr['MYR'] ?? 0; break; case '6': $originMoney = UserStockThaModel::where('user_id', $param['id']) ->where('stock_id', 'THB') ->value('usable_num'); - $rate = $marketArr['THB'] ?? 0; break; case '7': $originMoney = UserStockInModel::where('user_id', $param['id']) ->where('stock_id', 'INR') ->value('usable_num'); - $rate = $marketArr['INR'] ?? 0; break; case '8': //秒合约 $originMoney = UserContractSecModel::where('user_id', $param['id'])->value('usable_num'); - $rate = 1; break; case '9': $originMoney = UserStockSgdModel::where('user_id', $param['id']) ->where('stock_id', 'SGD') ->value('usable_num'); - $rate = $marketArr['SGD'] ?? 0; break; @@ -432,63 +446,54 @@ class UserService extends AdminBaseService $originMoney = UserStockFundModel::where('user_id', $param['id']) ->where('stock_id', 'USD') ->value('usable_num'); - $rate = $marketArr['USD'] ?? 0; break; case '11': $originMoney = UserStockOptionInrModel::where('user_id', $param['id']) ->where('stock_id', 'INR') ->value('usable_num'); - $rate = $marketArr['INR'] ?? 0; break; case '12': $originMoney = UserStockHkdModel::where('user_id', $param['id']) ->where('stock_id', 'HKD') ->value('usable_num'); - $rate = $marketArr['HKD'] ?? 0; break; case '14': $originMoney = UserStockGBXModel::where('user_id', $param['id']) ->where('stock_id', 'GBX') ->value('usable_num'); - $rate = $marketArr['GBX'] ?? 0; break; case '15': $originMoney = UserStockFurModel::where('user_id', $param['id']) ->where('stock_id', 'EUR') ->value('usable_num'); - $rate = $marketArr['EUR'] ?? 0; break; case '16': $originMoney = UserStockEurModel::where('user_id', $param['id']) ->where('stock_id', 'EUR') ->value('usable_num'); - $rate = $marketArr['EUR'] ?? 0; break; case '17': $originMoney = UserStockBrlModel::where('user_id', $param['id']) ->where('stock_id', 'BRL') ->value('usable_num'); - $rate = $marketArr['BRL'] ?? 0; break; case '18': $originMoney = UserStockJpModel::where('user_id', $param['id']) ->where('stock_id', 'JPY') ->value('usable_num'); - $rate = $marketArr['JPY'] ?? 0; break; case '19': $originMoney = UserForexModel::where('user_id', $param['id']) - ->where('stock_id', 'USD') + ->where('contract_id', 'USD') ->value('usable_num'); - $rate = $marketArr['USD'] ?? 0; break; default: @@ -496,6 +501,9 @@ class UserService extends AdminBaseService break; } + if (empty($originMoney)) { + $originMoney = 0; + } $diff = bcsub($amount, $originMoney, 18); // 未进行修改 if ($diff == 0) { @@ -724,8 +732,17 @@ class UserService extends AdminBaseService return $this->toData('0', 'success', []); } - $front = FileModel::where('id', $log->front_img)->value('path'); - $back = FileModel::where('id', $log->back_img)->value('path'); +// $front = FileModel::where('id', $log->front_img)->value('path'); +// $back = FileModel::where('id', $log->back_img)->value('path'); + + if ($log->front_img) { + $front = AwsS3Model::where('id', $log->front_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 = [ @@ -733,8 +750,8 @@ class UserService extends AdminBaseService 'name' => $log->name, 'code' => $log->code, 'country' => $country, - 'front_img' => $front, - 'back_img' => $back, + 'front_img' => $front ?? '', + 'back_img' => $back ?? '', 'lock_password' => $log->lock_password ]; @@ -1010,6 +1027,65 @@ class UserService extends AdminBaseService return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]); } } + + // 编辑用户的 customer_remark 字段 + public function editCustomerRemark($param) + { + try { + if (empty($param['user_id']) || !is_numeric($param['user_id'])) { + return $this->toData('1', 'Missing parameter user_id'); + } + if (empty($param['remark'])) { + return $this->toData('1', 'Missing parameter remark'); + } + $user = UserModel::where(['user_id'=>$param['user_id']])->find(); + if (empty($user)) { + return $this->toData('1', '操作的用户数据错误'); + } + $user->customer_remark = $param['remark']; + $user->save(); + return $this->toData('0', 'SUCCESS'); + } catch (\Exception $exception) { + return $this->toData('1', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]); + } + } + + // 编辑用户标签字段 + public function editUserLabel($param) + { + try { + if (empty($param['user_id']) || !is_numeric($param['user_id'])) { + return $this->toData('1', 'Missing parameter user_id'); + } + if (empty($param['label'])) { + return $this->toData('1', 'Missing parameter label'); + } + $user = UserModel::where(['user_id'=>$param['user_id']])->find(); + if (empty($user)) { + return $this->toData('1', '操作的用户数据错误'); + } + $user->label = $param['label']; + $user->save(); + + // 同步更新chat服务 + $userChatInfo = UserChatLinkModel::where(['user_id'=>$user->user_id, 'user_type'=>UserChatLinkModel::USER_CHAT_LINK_USER_TYPE_PC])->find(); + if (empty($userChatInfo)) { + return $this->toData('500', '该用户的聊天信息错误'); + } + $upChaData = [ + 'username' => $userChatInfo->chat_name, + 'label' => $param['label'], + ]; + $chatFriendsUrl = env('CHAT_SERVER.BASE_URL') . '/api/user'; + $chatFriendsRes = (new \app\utility\RequestChatServer())->ReqChatServer($chatFriendsUrl, $upChaData, 'PUT'); + if (!isset($chatFriendsRes['code']) || !$chatFriendsRes['code'] == 0) { + return $this->toData('500', 'chat服务错误:'.$chatFriendsRes['msg']); + } + return $this->toData('0', 'SUCCESS'); + } catch (\Exception $exception) { + return $this->toData('1', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]); + } + } } diff --git a/app/admin/service/VideoService.php b/app/admin/service/VideoService.php index f50952af..8c1756fa 100644 --- a/app/admin/service/VideoService.php +++ b/app/admin/service/VideoService.php @@ -1,5 +1,6 @@ toData('1', '参错错误'); + return $this->toData('400', '参错错误'); } if (empty($param['limit']) || !is_numeric($param['limit'])) { - return $this->toData('1', '参错错误'); + return $this->toData('400', '参错错误'); } $where = []; if (isset($param['title'])) { @@ -29,7 +30,7 @@ class VideoService extends AdminBaseService 'last_page' => $list->lastPage(), // 最后一页页码 ]); } catch (\Exception $exception) { - return $this->toData('100500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]); + return $this->toData('500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]); } } @@ -38,7 +39,7 @@ class VideoService extends AdminBaseService { try { if (empty($param['title']) || empty($param['cover_id']) || empty($param['video_id']) || empty($param['cover_url']) || empty($param['video_url'] || empty($param['state'])) ) { - return $this->toData('1', '参错错误'); + return $this->toData('400', '参错错误'); } $insert = VideoOnDemandModel::create([ 'title' => $param['title'], @@ -52,7 +53,7 @@ class VideoService extends AdminBaseService ]); return $this->toData('0', 'SUCCESS', ['insert_id' => $insert->id]); } catch (\Exception $exception) { - return $this->toData('100500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]); + return $this->toData('500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]); } } @@ -61,14 +62,14 @@ class VideoService extends AdminBaseService { try { if (empty($param['id'])) { - return $this->toData('1', 'Missing param id'); + return $this->toData('400', 'Missing param id'); } if (empty($param['title']) || empty($param['cover_id']) || empty($param['video_id']) || empty($param['cover_url']) || empty($param['video_url'] || empty($param['state'])) ) { - return $this->toData('1', '参错错误'); + return $this->toData('400', '参错错误'); } $ckInfo = VideoOnDemandModel::where('id', $param['id'])->find(); if (empty($ckInfo)) { - return $this->toData('1', '编辑的数据不存在'); + return $this->toData('500', '编辑的数据不存在'); } $ckInfo->title = $param['title']; $ckInfo->desc = $param['desc']; @@ -79,9 +80,96 @@ class VideoService extends AdminBaseService $ckInfo->sort = $param['sort']; $ckInfo->state = $param['state']; $ckInfo->save(); - return $this->toData('1', 'Successful'); + return $this->toData('0', 'success'); } catch (\Exception $exception) { - return $this->toData('100500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]); + return $this->toData('500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]); } } + + // 屏蔽词列表 + public function blockedWordList($param) + { + try { + if (empty($param['page']) || !is_numeric($param['page'])) { + return $this->toData('400', '参错错误'); + } + if (empty($param['limit']) || !is_numeric($param['limit'])) { + return $this->toData('400', '参错错误'); + } + $list = BlockedWordModel::order('id', 'desc')->paginate([ + 'list_rows' => $param['limit'], + 'page' => $param['page'], + ]); + return $this->toData('0', 'SUCCESS', [ + 'list' => $list->items(), // 当前页的数据 + 'page' => $list->currentPage(), // 当前页码 + 'total' => $list->total(), // 总记录数 + 'last_page' => $list->lastPage(), // 最后一页页码 + ]); + } catch (\Exception $exception) { + return $this->toData('500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]); + } + } + + // 新增屏蔽词 + public function blockedWordAdd($param) + { + try { + if (empty($param['word'])) { + return $this->toData('400', '参错错误'); + } + $blockedWord = BlockedWordModel::where(['word'=>$param['word']])->find(); + if (!empty($blockedWord)) { + return $this->toData('400', '已存在相同屏蔽词'); + } + $insert = BlockedWordModel::create([ + 'word' => $param['word'], + ]); + if (!$insert) { + return $this->toData('500', '添加失败'); + } + return $this->toData('0', 'SUCCESS'); + } catch (\Exception $exception) { + return $this->toData('500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]); + } + } + + // 编辑屏蔽词 + public function blockedWordEdit($param) + { + try { + if (empty($param['id']) || empty($param['word'])) { + return $this->toData('400', '参错错误'); + } + $blockedWord = BlockedWordModel::where(['id'=>$param['id']])->find(); + if (empty($blockedWord)) { + return $this->toData('400', '数据不存在'); + } + $blockedWord->word = $param['word']; + $blockedWord->save(); + return $this->toData('0', 'SUCCESS'); + } catch (\Exception $exception) { + return $this->toData('500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]); + } + } + + // 删除屏蔽词 + public function blockedWordDelete($param) + { + try { + if (empty($param['id'])) { + return $this->toData('400', '参错错误'); + } + $blockedWord = BlockedWordModel::where(['id'=>$param['id']])->find(); + if (empty($blockedWord)) { + return $this->toData('400', '数据不存在'); + } + $blockedWord->state = 0; + $blockedWord->save(); + return $this->toData('0', 'SUCCESS'); + } catch (\Exception $exception) { + return $this->toData('500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]); + } + } + } diff --git a/app/admin/validate/ChannelValidate.php b/app/admin/validate/ChannelValidate.php new file mode 100644 index 00000000..06a9bc4d --- /dev/null +++ b/app/admin/validate/ChannelValidate.php @@ -0,0 +1,34 @@ + 'require|integer', + 'limit' => 'require|integer', + 'id' =>'require|integer', + 'channel' => 'require', + 'agent_id' => 'require|integer' + ]; + + protected $message = [ + 'page.require' => '分页参数无效', + 'page.integer' => '分页参数无效', + 'limit.require' => '分页参数无效', + 'limit.integer' => '分页参数无效', + 'id.require' => '主键无效', + 'id.alphaNum' => '主键无效', + 'agent_id.require' => '代理ID参数缺少', + 'agent_id.integer' => '代理ID参数类型错误' + ]; + + + protected $scene = [ + 'list' => ['page','limit'], + 'add' => ['channel'], + 'edit' => ['id','channel'], + 'delete' => ['id'], + 'agent_channel_list' => ['page','limit'], + 'agent_created_channel' => ['agent_id','channel'], + ]; +} \ No newline at end of file diff --git a/app/home/controller/Document.php b/app/home/controller/Document.php index 4204ddaf..a474a042 100644 --- a/app/home/controller/Document.php +++ b/app/home/controller/Document.php @@ -41,6 +41,7 @@ class Document extends HomeBaseController 'title' => $item['title'], 'content' => $item['content'], 'id' => $item['id'], + 'type' => $item['type'], ]; } } diff --git a/app/home/controller/News.php b/app/home/controller/News.php index 219fad56..30f6ef10 100644 --- a/app/home/controller/News.php +++ b/app/home/controller/News.php @@ -2,9 +2,11 @@ namespace app\home\controller; +use app\model\PurchaseVipModel; use app\model\UserChatLinkModel; use Goutte\Client; use think\facade\Cache; +use think\facade\Config; use think\facade\Log; use think\Request; use think\response\Json; @@ -93,12 +95,16 @@ class News extends HomeBaseController */ public function testApi() { + $s3Config = Config::get('common.chat_server.bse_url'); + + $uniq = bin2hex(random_bytes(16)); $getEnv = env('ACCOUT_TYPE.ALL_IN_ONE'); return json([ 'code' => '0', 'message' => 'successful', - 'data' => phpversion(), + 'data' => $s3Config, 'env' => $getEnv, + 'random' => $uniq, ]); } diff --git a/app/home/controller/Upload.php b/app/home/controller/Upload.php index 96b5ec2c..bcbbbc3b 100644 --- a/app/home/controller/Upload.php +++ b/app/home/controller/Upload.php @@ -3,9 +3,12 @@ namespace app\home\controller; use app\home\validate\UploadValidate; +use app\model\AwsS3Model; use app\model\ConfigModel; use app\model\FileModel; +use Aws\S3\S3Client; use think\exception\ValidateException; +use think\facade\Config; use think\facade\Filesystem; use think\facade\Log; use think\response\Json; @@ -20,24 +23,59 @@ class Upload extends HomeBaseController */ public function uploadHeaderImage(): Json { - $filess = $_FILES['file']?? ""; try { // 获取文件 $file = $this->request->file('file'); + if (!$file) { + return json(['code' => 400, 'message' => 'No file uploaded']); + } // 参数校验 validate(UploadValidate::class)->scene('uploadImage')->check(['image' => $file]); - // 将文件存储在本地 - $name = Filesystem::disk('local')->putFile('', $file); - $path = '/bs/image/'.$name; - // 入库 - $id = FileModel::insertFile($path, 2); - return json(['code' => '0', 'message' => 'Request successful.','data' => ['id' => $id]]); + $maxSize = 15 * 1024 * 1024; //限制15M + if ($file->getSize() > $maxSize) { + return json(['code' => 400, 'message' => 'Upload file is too large']); + } + $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' => fopen($file->getRealPath(), 'r'), + 'ContentType' => $file->getOriginalMime(), // 设置文件的MIME, 不然s3会以流式存储 + ]); + if (empty($result) || empty($result['ObjectURL'])) { + return json(['code' => 400, 'message' => '上传s3失败']); + } + // 记录上传的文件 + $resData = AwsS3Model::create([ + 'name' => $fileName, + 's3_url' => $result['ObjectURL'], + 'size' => $file->getSize(), + 'mime' => $file->getOriginalMime(), + 'ext' => $file->getOriginalExtension(), + ]); + return json(['code' => '0', 'message' => '上传成功', 'data' => [ + 'id' => $resData->id, + 'url' => $result['ObjectURL'], + 'name' => $fileName, + 'size' => $file->getSize(), + 'mime' => $file->getOriginalMime(), + 'ext'=> $file->getOriginalExtension(), + ]]); }catch (ValidateException $validateException){ - // 参数校验失败 异常类 - $message = $validateException->getError(); - return json(['code' => '1004001', 'message' => $message]); + return json(['code' => '1004001', 'message' => $validateException->getError()]); }catch (\Exception $exception){ - return json(['code' => '100500', 'message' => 'System error','data' => [$exception->getMessage(), $exception->getTrace(), $exception->getFile(),$filess]]); + return json(['code' => '100500', 'message' => 'System error', 'data' => [$exception->getMessage(), $exception->getTrace(), $exception->getFile()]]); } } public function uploadRechargeImage(): Json diff --git a/app/home/controller/User.php b/app/home/controller/User.php index fe6a2740..ff44d199 100644 --- a/app/home/controller/User.php +++ b/app/home/controller/User.php @@ -319,4 +319,10 @@ class User extends HomeBaseController $returnData = (new UserService())->formalLogin($this->request->userId); return json($returnData); } + + public function userAccessLog() + { + $returnData = (new UserService())->userAccessLog($this->request->userId, $this->request->post()); + return json($returnData); + } } \ No newline at end of file diff --git a/app/home/controller/Video.php b/app/home/controller/Video.php index 727c01ab..66360588 100644 --- a/app/home/controller/Video.php +++ b/app/home/controller/Video.php @@ -18,4 +18,11 @@ class Video extends HomeBaseController $returnData = (new VideoService())->getVideoOnDemandDetail($this->request->post()); return json($returnData); } + + // 获取屏蔽词列表 + public function blockedWordList() + { + $returnData = (new VideoService())->blockedWordList($this->request->post()); + return json($returnData); + } } diff --git a/app/home/route/app.php b/app/home/route/app.php index fcb258ff..8575cf8f 100644 --- a/app/home/route/app.php +++ b/app/home/route/app.php @@ -190,6 +190,7 @@ Route::group('/',function (){ Route::post('user/apply_test', 'User/applyTest'); Route::post('user/test_login', 'User/testLogin'); Route::post('user/formal_login', 'User/formalLogin'); + Route::post('user/user_access_log', 'User/userAccessLog'); //记录用户访问每个页面日志 Route::post('payment_list', 'Pay/payChannel'); //获取充值渠道 @@ -270,6 +271,7 @@ Route::group('/',function (){ // 视频点播相关 Route::post('video/video_on_demand_list', 'Video/videoOnDemandList'); // 获取视频点播列表 Route::post('video/video_on_demand_detail', 'Video/videoOnDemandDetail'); // 获取某个点播配置详情 + Route::post('video/blocked_word_list', 'Video/blockedWordList'); //获取屏蔽词列表 })->middleware(\app\home\middleware\AuthMiddleware::class); @@ -283,7 +285,8 @@ Route::group('/',function (){ Route::post('get_ip', 'Login/getIP'); Route::get('get_news', 'News/index'); - Route::get('test', 'News/testApi'); + Route::post('test', 'News/testApi'); + Route::post('test_api', 'user/userAccessLog'); })->allowCrossDomain($header); diff --git a/app/home/service/LoginService.php b/app/home/service/LoginService.php index fdabca5b..a85d20e2 100644 --- a/app/home/service/LoginService.php +++ b/app/home/service/LoginService.php @@ -98,6 +98,7 @@ class LoginService extends BaseHomeService $param['invite_code'] = $param['invite_code'] ?? ''; $param['agent_code'] = $param['agent_code'] ?? ''; + $chCode = $param['ch_code'] ?? ''; // 注册渠道标识码 // 邮件注册参数校验 validate(LoginValidate::class)->scene('emailRegister')->check($param); @@ -149,14 +150,14 @@ class LoginService extends BaseHomeService if ($agentId == 0) { $agentId = AdminModel::getIdByInviteCode($agentCode); if ($agentId <= 0) { - return $this->toData('100400', 'The invitation code is invalid.', []); + return $this->toData('100401', 'The invitation code is invalid.', []); } } } else { // 是否必须填写有效的邀请码 $inviteCodeIsRequired = env("REG_USER.INVITE_CODE_REQUIRED"); if ($parentUserId <= 0 && $inviteCodeIsRequired >= 1) { - return $this->toData('100400', 'The invitation code is invalid.', []); + return $this->toData('100402', 'The invitation code is invalid.', []); } } @@ -165,22 +166,57 @@ class LoginService extends BaseHomeService $salt = env('ENCRYPT.SALT'); $password = (new UnqId())->encryptPassword($param['password'], $salt); $userInviteCode = $this->getUniqInviteCode(); - Log::info("邮箱注册 - agentId=".$agentId); // 需要开启事务 - \think\facade\Db::transaction(function () use ($email, $userNo, $userInviteCode, $parentUserId, $password, $ip, $salt, $agentId) { - // 生成用户数据 - $userId = UserModel::emailRegister($email, $userNo, $userInviteCode, $parentUserId, $password, $ip, $salt, 1, $agentId); + \think\facade\Db::transaction(function () use ($chCode, $email, $userNo, $userInviteCode, $parentUserId, $password, $ip, $salt, $agentId) { + // 截取邮箱@前的部分作为用户名称 + $pos = strpos($email, '@'); + if ($pos !== false) { + $userNickName = substr($email, 0, $pos); + } + // 查询父级用户 + $parentIds = ''; + $originUserId = 0; + if($parentUserId > 0){ + $parentUser = UserModel::where('user_id', $parentUserId)->findOrEmpty(); + if($parentUser){ + $parentIds = $parentUser['parent_ids']? $parentUser['parent_ids'].','.$parentUserId : $parentUserId; + // 如果祖先id = 0 说明这个父级就是祖先id + $originUserId = $parentUser['origin_user_id'] == 0 ? $parentUserId : $parentUser['origin_user_id']; + } + } + $regUser = UserModel::create([ + 'user_no' => $userNo, + 'nick_name' => $userNickName ?? 'user_' . time(), + 'email' => $email, + 'invite_code' => $userInviteCode, + 'parent_id' => $parentUserId, + 'agent_id' => $agentId, + 'login_password' => $password, + 'salt' => $salt, + 'reg_ip' => $ip, + 'is_test_user' => UserModel::IS_TEST_USER_NO, + 'origin_user_id' => $originUserId, + 'ch_code' => $chCode, + 'parent_ids' => $parentIds, + 'create_time' => date('Y-m-d H:i:s'), + 'update_time' => date('Y-m-d H:i:s'), + ]); + $userId = $regUser->user_id; + // 生成钱包地址 (new UserService())->doRegInitUserInfo($userId, $parentUserId); - // 注册聊天账号 + // 请求聊天服务,注册聊天账号 $chatData = [ 'Username' => $userNo, 'Password' => '123456', + 'Nickname' => $regUser->nick_name, + 'Avatar' => env('USER.DEFAULT_HEAD_IMG_PATH'), + 'Email' => $regUser->email, ]; $chatUrl = env('CHAT_SERVER.BASE_URL') . '/api/user/register'; $chatRes = (new \app\utility\RequestChatServer())->ReqChatServer($chatUrl, $chatData); if (!isset($chatRes['data']['uuid'])) { - return $this->toData('100400', 'Failed to register a chat account.', []); + return $this->toData('100400', '注册聊天账号失败,请稍后再试'); } // 绑定注册账号与聊天账号 UserChatLinkModel::create([ @@ -189,7 +225,6 @@ class LoginService extends BaseHomeService 'chat_uuid' => $chatRes['data']['uuid'], 'chat_name' => $chatRes['data']['username'] ]); - Log::info("邮箱注册 - 用户注册chat账号 - user_id=".$userId. " chat_uiud=".$chatRes['data']['uuid']); // 如果有代理,绑定到代理下一个客服(轮询客服绑定) if ($agentId > 0 ) { $customerIds = AdminModel::getCustomerIdsByAgentId($agentId); // 获取代理下的所有客服ID @@ -218,7 +253,7 @@ class LoginService extends BaseHomeService } // 将注册账号的chat_id与绑定客服的chat_id加为好友 Log::info("邮箱注册 - 获取去客服聊天账号信息, $tagCustomerId=".$tagCustomerId); - $customerChatInfo = UserChatLinkModel::where(['user_id'=>$tagCustomerId, 'user_type'=>2])->find(); //查询客服的聊天账号uuid + $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.', []); } @@ -226,18 +261,17 @@ class LoginService extends BaseHomeService 'UserUuid' => $chatRes['data']['uuid'], 'CustomerUuid' => $customerChatInfo->chat_uuid, ]; - Log::info("邮箱注册 - 请求聊天夫加好友=".$tagCustomerId); $chatFriendsUrl = env('CHAT_SERVER.BASE_URL') . '/api/eachOtherFriends'; $chatFriendsRes = (new \app\utility\RequestChatServer())->ReqChatServer($chatFriendsUrl, $chatFriendsData); - Log::info("邮箱注册 - chat服务加好友结果:".json_encode($chatFriendsRes)); + Log::info("邮箱注册 - 用户与客服加好友结果:".json_encode($chatFriendsRes)); // 将当前用户加入到代理创建的群聊中 【需要查出当前用户的代理创建的群聊信息】 - $agentGroup = UserChatGroupModel::where(['user_id'=>$agentId])->find(); + $agentGroup = UserChatGroupModel::where(['user_id'=>$agentId,'remark'=>UserChatGroupModel::USER_CHAT_GROUP_REMARK_ADMIN_INIT])->find(); if (empty($agentGroup)) { - return $this->toData('100400', 'The chat group is error.', []); + return $this->toData('100400', 'The chat group data error.'); } $joinChatGroupUrl = env('CHAT_SERVER.BASE_URL') . '/api/group/join/'.$chatRes['data']['uuid'].'/'.$agentGroup->group_uuid; $joinChatGroupRes = (new \app\utility\RequestChatServer())->ReqChatServer($joinChatGroupUrl, []); - + Log::info("邮箱注册 - 用户与客服加好友结果:".json_encode($joinChatGroupRes)); } }); // 删除缓存 @@ -413,6 +447,7 @@ class LoginService extends BaseHomeService $param['invite_code'] = $param['invite_code'] ?? ''; $param['agent_code'] = $param['agent_code'] ?? ''; + $chCode = $param['ch_code'] ?? ''; // 短信注册参数校验 validate(LoginValidate::class)->scene('smsRegister')->check($param); @@ -480,15 +515,47 @@ class LoginService extends BaseHomeService $userInviteCode = $this->getUniqInviteCode(); // 需要开启事务 - \think\facade\Db::transaction(function () use ($param, $userNo, $userInviteCode, $parentUserId, $password, $ip, $salt, $agentId) { + \think\facade\Db::transaction(function () use ($chCode, $param, $userNo, $userInviteCode, $parentUserId, $password, $ip, $salt, $agentId) { // 生成用户数据 - $userId = UserModel::phoneRegister($param['nation'], $param['phone'], $userNo, $userInviteCode, $parentUserId, $password, $ip, $salt, 1, $agentId); + $parentIds = ''; + $originUserId = 0; + if($parentUserId > 0){ + $parentUser = UserModel::where('user_id', $parentUserId)->findOrEmpty(); + if($parentUser){ + $parentIds = $parentUser['parent_ids']? $parentUser['parent_ids'].','.$parentUserId : $parentUserId; + // 如果祖先id = 0 说明这个父级就是祖先id + $originUserId = $parentUser['origin_user_id'] == 0 ? $parentUserId : $parentUser['origin_user_id']; + } + } + $regUser = UserModel::create([ + 'country_code' => $param['nation'], + 'phone_number' => $param['phone'], + 'user_no' => $userNo, + 'invite_code' => $userInviteCode, + 'parent_id' => $parentUserId, + 'agent_id' => $agentId, + 'login_password' => $password, + 'salt' => $salt, + 'reg_ip' => $ip, + 'is_test_user' => UserModel::IS_TEST_USER_NO, + 'nick_name' => 'user_'.substr($param['phone'], -4), + 'origin_user_id' => $originUserId, + 'parent_ids' => $parentIds, + 'ch_code' => $chCode, + 'create_time' => date('Y-m-d H:i:s'), + 'update_time' => date('Y-m-d H:i:s'), + + ]); + $userId = $regUser->user_id; + // 生成钱包地址 (new UserService())->doRegInitUserInfo($userId, $parentUserId); // 注册聊天账号 $chatData = [ 'Username' => $userNo, 'Password' => '123456', + 'Nickname' => $regUser->nick_name, + 'Avatar' => env('USER.DEFAULT_HEAD_IMG_PATH'), ]; $chatUrl = env('CHAT_SERVER.BASE_URL') . '/api/user/register'; $chatRes = (new \app\utility\RequestChatServer())->ReqChatServer($chatUrl, $chatData); @@ -527,7 +594,7 @@ class LoginService extends BaseHomeService ]); } // 将注册账号的chat_id与绑定客服的chat_id加为好友 - $customerChatInfo = UserChatLinkModel::where('user_id', $tagCustomerId)->find(); //查询客服的聊天账号uuid + $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.', []); } @@ -539,12 +606,13 @@ class LoginService extends BaseHomeService $chatFriendsRes = (new \app\utility\RequestChatServer())->ReqChatServer($chatFriendsUrl, $chatFriendsData); Log::info("手机号注册 - chat服务加好友结果:".json_encode($chatFriendsRes)); // 将当前用户加入到代理创建的群聊中 【需要查出当前用户的代理创建的群聊信息】 - $agentGroup = UserChatGroupModel::where(['user_id'=>$agentId])->find(); + $agentGroup = UserChatGroupModel::where(['user_id'=>$agentId,'remark'=>UserChatGroupModel::USER_CHAT_GROUP_REMARK_ADMIN_INIT])->find(); if (empty($agentGroup)) { return $this->toData('100400', 'The chat group is error.', []); } $joinChatGroupUrl = env('CHAT_SERVER.BASE_URL') . '/api/group/join/'.$chatRes['data']['uuid'].'/'.$agentGroup->group_uuid; $joinChatGroupRes = (new \app\utility\RequestChatServer())->ReqChatServer($joinChatGroupUrl, []); + Log::info("手机号注册 - 用户与客服加好友结果:".json_encode($joinChatGroupRes)); } }); diff --git a/app/home/service/UserService.php b/app/home/service/UserService.php index 9bbe8811..e9acca8b 100644 --- a/app/home/service/UserService.php +++ b/app/home/service/UserService.php @@ -4,10 +4,12 @@ namespace app\home\service; use app\home\validate\UserValidate; use app\model\AwsIvsModel; +use app\model\AwsS3Model; use app\model\CountryModel; use app\model\CustomerRelationalModel; use app\model\FileModel; use app\model\PurchaseVipModel; +use app\model\UserAccessLogModel; use app\model\UserChatGroupModel; use app\model\UserChatLinkModel; use app\model\UserContractModel; @@ -20,6 +22,7 @@ use app\model\UserModel; use app\model\UserMoneyLogModel; use app\model\UserMoneyModel; use app\model\UserStockHkdModel; +use app\model\UserStockLogModel; use app\model\UserStockModel; use app\utility\Jwt; use app\utility\UnqId; @@ -138,7 +141,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', $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,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.', []); } @@ -154,7 +157,10 @@ class UserService extends BaseHomeService // 获取头像 $headPath = env('USER.DEFAULT_HEAD_IMG_PATH'); if ($info['head_img_id'] > 0) { - $headPath = FileModel::getFilePath($info['head_img_id']); + $s3Info = AwsS3Model::where(['id'=>$info['head_img_id']])->find(); + if (!empty($s3Info)) { + $headPath = $s3Info->s3_url; + } } $key = 'LEVERAGE:' . $userId; @@ -166,7 +172,7 @@ class UserService extends BaseHomeService $leverageNum= empty($leverageNum) ? 1: $leverageNum; // 查询用户的chat_uuid - $userChatInfo = UserChatLinkModel::where('user_id', $userId)->find(); + $userChatInfo = UserChatLinkModel::where(['user_id'=>$userId,'user_type'=>UserChatLinkModel::USER_CHAT_LINK_USER_TYPE_PC])->find(); $userChatUuid = ""; $userChatName = ""; if (!empty($userChatInfo)) { @@ -178,7 +184,7 @@ class UserService extends BaseHomeService $customerChatName = ""; $customerRelationInfo = CustomerRelationalModel::where('user_id', $userId)->find(); //查询用户关联的客服账号信息 if ($customerRelationInfo) { - $customerChatInfo = UserChatLinkModel::where(['user_id'=>$customerRelationInfo->customer_id, 'user_type'=>2])->find(); //查询客服的chat账号 + $customerChatInfo = UserChatLinkModel::where(['user_id'=>$customerRelationInfo->customer_id, 'user_type'=>UserChatLinkModel::USER_CHAT_LINK_USER_TYPE_ADMIN])->find(); //查询客服的chat账号 if ($customerChatInfo) { $customerChatUuid = $customerChatInfo->chat_uuid; $customerChatName = $customerChatInfo->chat_name; @@ -198,11 +204,13 @@ class UserService extends BaseHomeService // 检测用户是否为有效VIP [判断规则 - 用户购买过VIP, 每个VIP有效期30天] $isVip = false; - $purchaseInfo = PurchaseVipModel::where(['user_id'=>$userId])->order('id', 'desc')->find(); + $vipExpire = ""; //vip到期时间 + $purchaseInfo = PurchaseVipModel::where(['user_id'=>$userId])->find(); if (!empty($purchaseInfo)) { if ($purchaseInfo->expire >= date("Y-m-d H:i:s")) { $isVip = true; } + $vipExpire = $purchaseInfo->expire; } // 返回数据 @@ -234,6 +242,9 @@ class UserService extends BaseHomeService 'group_chat_name' => $group_chat_name, 'group_chat_uuid' => $group_chat_uuid, 'is_vip' => $isVip, + 'vip_expire' => $vipExpire, + 'customer_remark' => $info['customer_remark'], + 'label' => $info['label'], ]); } catch (\Exception $exception) { return $this->toData('100500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]); @@ -256,7 +267,7 @@ class UserService extends BaseHomeService if (empty($vipPurchaseCfg)) { return $this->toData('100400', 'vip config error', []); } - // 购买vip所需的货币类型检测 + // 购买vip所需的货币类型检测 [产品确定使用美股支付 USD] if (empty($vipPurchaseCfg['stock_id'])) { return $this->toData('100400', 'vip config error', []); } @@ -271,8 +282,8 @@ class UserService extends BaseHomeService return $this->toData('100400', 'vip config error', []); } $vipDay = $vipPurchaseCfg['vip_day']; - // 查询用户余额是否足够 - $userMoney = UserMoneyModel::where(['user_id'=>$userId,'stock_id'=>$stockId])->find(); + // 查询用户美股余额是否足够 【产品确定用美股余额支付】 + $userMoney = UserStockModel::where(['user_id'=>$userId,'stock_id'=> $stockId])->find(); if (empty($userMoney)) { return $this->toData('100400', ' The user USD balance is insufficient ', []); } @@ -281,44 +292,45 @@ class UserService extends BaseHomeService return $this->toData('100400', ' The user USD balance is insufficient ', []); } - // 查询是否有购买vip记录, 计算用户vip到期时间 - $expireTime = date("Y-m-d H:i:s"); - $vipLog = PurchaseVipModel::where(['user_id'=>$userId])->order('id', 'desc')->find(); - if (!empty($vipLog)) { - if (empty($vipLog->expire)) { - return $this->toData('100400', ' The vip expire error ', []); - } - if ($vipLog->expire >= $expireTime) { - $expireTimestamp = strtotime('+30 days', strtotime($vipLog->expire)); - $expireTime = date("Y-m-d H:i:s", $expireTimestamp); - } - } else { - $expireTimestamp = strtotime('+30 days', time()); - $expireTime = date("Y-m-d H:i:s", $expireTimestamp); - } - // 记录购买vip信息, 扣除用户金额 - Db::transaction(function () use ($userId, $userMoneyNum, $vipPrice, $expireTime, $stockId) { - // 添加购买vip记录 - PurchaseVipModel::create([ - 'user_id' => $userId, - 'amount' => $vipPrice, - 'stock_id' => $stockId, - 'expire' => $expireTime - ]); + Db::transaction(function () use ($userId, $userMoneyNum, $vipPrice, $stockId) { // 扣除用户USD - UserMoneyModel::where(['user_id'=>$userId,'stock_id'=>$stockId])->where('usable_num', ">=", $vipPrice)->dec('usable_num', $vipPrice)->update(); + UserStockModel::where(['user_id'=>$userId,'stock_id'=>$stockId])->where('usable_num', ">=", $vipPrice)->dec('usable_num', $vipPrice)->update(); // 添加用户USD变更日志 - UserMoneyLogModel::create([ + UserStockLogModel::create([ 'user_id' => $userId, 'change_type' => 101, 'stock_id' => $stockId, 'before_num' => $userMoneyNum, 'change_num' => -$vipPrice, - 'order_id' => uniqid('vip_', true), + 'create_time' => date('Y-m-d H:i:s'), + 'update_time' => date('Y-m-d H:i:s') ]); + // 查询用户是否开通过vip,更新用户vip到期时间 + $vipLog = PurchaseVipModel::where(['user_id'=>$userId])->find(); + $expireTime = date("Y-m-d H:i:s"); + if (!empty($vipLog)) { + if (empty($vipLog->expire)) { + return $this->toData('100400', ' The vip expire error '); + } + if ($vipLog->expire >= $expireTime) { + $expireTimestamp = strtotime('+30 days', strtotime($vipLog->expire)); + $expireTime = date("Y-m-d H:i:s", $expireTimestamp); + } + $vipLog->expire = $expireTime; + $vipLog->save(); + } else { + $expireTimestamp = strtotime('+30 days', time()); + $expireTime = date("Y-m-d H:i:s", $expireTimestamp); + PurchaseVipModel::create([ + 'user_id' => $userId, + 'amount' => $vipPrice, + 'stock_id' => $stockId, + 'expire' => $expireTime + ]); + } }); - return $this->toData('0', 'successful', ['expire'=>$expireTime]); + return $this->toData('0', 'successful'); } catch (\Exception $exception) { return $this->toData('100500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]); } @@ -423,23 +435,41 @@ class UserService extends BaseHomeService try { // 主键 if (empty($userId) || $userId <= 0) { - return $this->toData('100403', 'Please log in first.', []); + return $this->toData('100403', 'Please log in first.'); } - // 参数校验 validate(UserValidate::class)->scene('updateHeadImg')->check($param); $fileId = $param['file_id']; - - // 文件是否存在 - $file = FileModel::getById($fileId); - if (empty($file)) { - return $this->toData('100400', 'The file does not exist.', []); + // 查询头像信息 + $avatarInfo = AwsS3Model::where(['id'=>$fileId])->find(); + if (empty($avatarInfo)) { + return $this->toData('500', '头像信息错误'); } - - - // 设置 - UserModel::updateFieldsByUserId(['head_img_id' => $fileId], $userId); - return $this->toData('0', 'Modification successful.'); + // 修改用户头像 + $user = UserModel::where(['user_id'=>$userId])->find(); + if (empty($user)) { + return $this->toData('500', '用户数据错误'); + } + $user->head_img_id = $fileId; + $user->save(); + + // 查询用户的chat信息 + $userChatInfo = UserChatLinkModel::where(['user_id'=>$userId, 'user_type'=>UserChatLinkModel::USER_CHAT_LINK_USER_TYPE_PC])->find(); + if (empty($userChatInfo)) { + return $this->toData('500', '该用户的聊天信息错误'); + } + // 头像修改后需要同步通知给聊天服 + $upChaData = [ + 'Username' => $userChatInfo->chat_name, + 'Password' => '123456', + 'Nickname' => $user->nick_name, + 'Email' => $user->email, + 'Avatar' => $avatarInfo->s3_url, + + ]; + $chatFriendsUrl = env('CHAT_SERVER.BASE_URL') . '/api/user'; + $chatFriendsRes = (new \app\utility\RequestChatServer())->ReqChatServer($chatFriendsUrl, $upChaData, 'PUT'); + return $this->toData($chatFriendsRes['code'], $chatFriendsRes['msg'], [$chatFriendsRes['data']]); } catch (ValidateException $validateException) { $message = $validateException->getMessage(); return $this->toData('100400', $message, []); @@ -465,26 +495,43 @@ class UserService extends BaseHomeService // 参数校验 validate(UserValidate::class)->scene('updateInfo')->check($param); - // 查找用户信息 - $user = UserModel::getFieldsByUserId('user_id,nick_name,first_name,first_name,gender', $userId); + // 修改用户信息 + $user = UserModel::where(['user_id'=>$userId])->find(); if (empty($user)) { return $this->toData('100403', 'Please log in first.', []); } + $user->nick_name = $param['nick_name']; + $user->gender = $param['gender']; + $user->lastName = $param['last_name'] ?? $user->lastName; + $user->first_name = $param['first_name'] ?? $user->first_name; + $user->save(); + + // 获取用户chat信息 + $userChatInfo = UserChatLinkModel::where(['user_id'=>$userId,'user_type'=>UserChatLinkModel::USER_CHAT_LINK_USER_TYPE_PC])->find(); + if (empty($userChatInfo)) { + return $this->toData('500', '该用户的聊天信息错误'); + } + // 获取用户头像 + $avatarUrl = ""; + if (!empty($user->head_img_id)) { + $avatarInfo = AwsS3Model::where(['id'=>$user->head_img_id])->find(); + if (empty($avatarInfo)) { + return $this->toData('500', '头像信息错误'); + } + $avatarUrl = $avatarInfo->s3_url; + } + // 修改信息同步到聊天服 + $upChaData = [ + 'Username' => $userChatInfo->chat_name, + 'Password' => '123456', + 'Nickname' => $user->nick_name, + 'Email' => $user->email, + 'Avatar' => $avatarUrl, + ]; + $chatFriendsUrl = env('CHAT_SERVER.BASE_URL') . '/api/user'; + $chatFriendsRes = (new \app\utility\RequestChatServer())->ReqChatServer($chatFriendsUrl, $upChaData, 'PUT'); + return $this->toData($chatFriendsRes['code'], $chatFriendsRes['msg'], [$chatFriendsRes['data']]); - $nickName = $param['nick_name']; - $gender = $param['gender']; - $lastName = $param['last_name'] ?? $user['last_name']; - $first_name = $param['first_name'] ?? $user['first_name']; - - UserModel::updateFieldsByUserId([ - 'nick_name' => $nickName, - 'first_name' => $first_name, - 'last_name' => $lastName, - 'gender' => $gender, - ], $userId); - - // 返回 - return $this->toData('0', 'Modification successful.', []); } catch (ValidateException $validateException) { $message = $validateException->getError(); return $this->toData('100400', $message); @@ -1762,4 +1809,24 @@ class UserService extends BaseHomeService 'token' => $token, ]); } + + // 记录用户访问每个页面的日志 + public function userAccessLog($userId, $param) + { + try { + if (empty($param['page_url'])) { + return $this->toData('400', '参数错误'); + } + $userAccessLog = UserAccessLogModel::create([ + 'user_id' => $userId, + 'page_url' => $param['page_url'], + ]); + if (empty($userAccessLog)) { + return $this->toData('500', '添加数据失败'); + } + return $this->toData('0', 'success'); + } catch (\Exception $exception) { + return $this->toData('500', 'The system is busy.', [$exception->getMessage(), $exception->getLine(), $exception->getTrace()]); + } + } } diff --git a/app/home/service/UserVerifyService.php b/app/home/service/UserVerifyService.php index fdf12428..33bb9f9a 100644 --- a/app/home/service/UserVerifyService.php +++ b/app/home/service/UserVerifyService.php @@ -31,9 +31,9 @@ class UserVerifyService extends BaseHomeService return $this->toData('100400','Invalid front_img'); } - if(empty($params['back_img']) || !is_numeric($params['back_img'])){ - return $this->toData('100400','Invalid back_img'); - } +// if(empty($params['back_img']) || !is_numeric($params['back_img'])){ +// return $this->toData('100400','Invalid back_img'); +// } // 判断用户状态 $user = UserModel::where('user_id', $userId)->find(); @@ -62,10 +62,10 @@ class UserVerifyService extends BaseHomeService return $this->toData('100400','front_img error'); } - $back = FileModel::where('id',$params['back_img'])->find(); - if(empty($back)){ - return $this->toData('100400','back_img error'); - } +// $back = FileModel::where('id',$params['back_img'])->find(); +// if(empty($back)){ +// return $this->toData('100400','back_img error'); +// } //锁屏密码 $lockPassword = ''; @@ -83,7 +83,7 @@ class UserVerifyService extends BaseHomeService $userVerify->code = $params['code']; $userVerify->name = $params['name']; $userVerify->front_img = $params['front_img']; - $userVerify->back_img = $params['back_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'); diff --git a/app/home/service/VideoService.php b/app/home/service/VideoService.php index f9d98cd9..25753eec 100644 --- a/app/home/service/VideoService.php +++ b/app/home/service/VideoService.php @@ -1,6 +1,7 @@ toData('1', '参错错误'); + return $this->toData('400', '参错错误'); } if (empty($param['limit']) || !is_numeric($param['limit'])) { - return $this->toData('1', '参错错误'); + return $this->toData('400', '参错错误'); } $list = VideoOnDemandModel::where(['state'=>1])->order('sort', 'desc')->paginate([ 'list_rows' => $param['limit'], @@ -25,7 +26,7 @@ class VideoService extends BaseHomeService 'last_page' => $list->lastPage(), // 最后一页页码 ]); } catch (\Exception $exception) { - return $this->toData('100500', 'The system is busy.', []); + return $this->toData('500', 'The system is busy.', []); } } @@ -33,16 +34,26 @@ class VideoService extends BaseHomeService { try { if (empty($param['id']) || !is_numeric($param['id'])) { - return $this->toData('1', '参错错误'); + return $this->toData('400', '参错错误'); } $info = VideoOnDemandModel::where(['id'=>$param['id']])->find(); if (empty($info)) { - return $this->toData('0', 'Successful', []); + return $this->toData('500', 'Successful', []); } - return $this->toData('0', 'Successful', $info->toArray()); } catch (\Exception $exception) { - return $this->toData('100500', 'The system is busy.', []); + return $this->toData('500', 'The system is busy.', []); + } + } + + // 获取屏蔽词列表 + public function blockedWordList($param) + { + try { + $list = BlockedWordModel::where(['state'=>1])->column(['word']); + return $this->toData('0', 'Successful', $list); + } catch (\Exception $exception) { + return $this->toData('500', 'The system is busy.'); } } } \ No newline at end of file diff --git a/app/home/service/WalletService.php b/app/home/service/WalletService.php index 93fd0cb9..7b0465ba 100644 --- a/app/home/service/WalletService.php +++ b/app/home/service/WalletService.php @@ -428,7 +428,7 @@ class WalletService extends BaseHomeService private function getUserUsStock($data, int $type = 0): array { try { - validate(WalletValidate::class)->scene('getUserBalance')->check($data);z + validate(WalletValidate::class)->scene('getUserBalance')->check($data); if ($type == 0) { return UserStockModel::getUserStockList($data['user_id']); } else { diff --git a/app/home/validate/UploadValidate.php b/app/home/validate/UploadValidate.php index 85153f30..14e962d4 100644 --- a/app/home/validate/UploadValidate.php +++ b/app/home/validate/UploadValidate.php @@ -5,7 +5,7 @@ namespace app\home\validate; class UploadValidate extends BaseHomeValidate { protected $rule = [ - 'image' => 'require|fileSize:10485760|fileExt:jpg,jpeg,png', + 'image' => 'require|fileSize:15728640|fileMime:image/jpeg,image/png,image/webp,image/bmp', ]; protected $message = [ diff --git a/app/model/AdminModel.php b/app/model/AdminModel.php index 4401e9b3..b18dbf40 100644 --- a/app/model/AdminModel.php +++ b/app/model/AdminModel.php @@ -78,4 +78,10 @@ class AdminModel extends BaseModel return 0; } return $self; - }} \ No newline at end of file + } + + public static function getCustomerIdsByAgentId($agentId): array + { + return self::where('parent_id', $agentId)->column('id'); + } +} \ No newline at end of file diff --git a/app/model/AgentChannelListModel.php b/app/model/AgentChannelListModel.php new file mode 100644 index 00000000..7b56b3b2 --- /dev/null +++ b/app/model/AgentChannelListModel.php @@ -0,0 +1,7 @@ +toData('500', '请求方法不在支持列表中'); + } Log::info("请求URL==".$url." 请求Param==".json_encode($data)); $resBody = []; $client = new Client(); - $response = $client->post($url, [ - 'json' => $data, - ]); + if ($method == 'PUT') { + $response = $client->put($url, [ + 'json' => $data, + ]); + } else { + $response = $client->post($url, [ + 'json' => $data, + ]); + } $statusCode = $response->getStatusCode(); - Log::error("请求聊天服返回:code==".$statusCode); - Log::error("请求聊天服返回:body==". $response->getBody()); + Log::error("请求聊天服返回:code==".$statusCode." body==". $response->getBody()); if ($statusCode == 200) { $resBody = json_decode($response->getBody(), true); // 转换为数组 } return $resBody; } catch (GuzzleException $e) { - Log::error("请求聊天服异常 - guzzle: " . $e->getMessage()); - return []; + Log::error("请求聊天服务异常 - guzzle: " . $e->getMessage()); + return $this->toData('500', $e->getMessage()); } catch (\Exception $exception) { - Log::error("请求聊天服异常 - exc:" . $exception->getMessage()); - return []; + Log::error("请求聊天服务异常 - exception: " . $exception->getMessage()); + return $this->toData('500', $exception->getMessage()); } } } \ No newline at end of file