8000 开发客服功能,页面分为普通用户和客服两个页面 · lpzhi/laravel_template_with_vue@bb74474 · GitHub
[go: up one dir, main page]

Skip to content

Commit bb74474

Browse files
committed
开发客服功能,页面分为普通用户和客服两个页面
1 parent 3e78275 commit bb74474

File tree

18 files changed

+1340
-168
lines changed

18 files changed

+1340
-168
lines changed

api/app/Http/Controllers/Admin/LoginController.php

Lines changed: 21 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414
use Faker\Factory;
1515
use App\GatewayClient\Gateway;
1616
use Illuminate\Support\Facades\Storage;
17-
use ZipArchive;
18-
use App\Http\Controllers\Admin\HZip;
1917

2018
/**
2119
* @group 管理员登陆管理
@@ -33,60 +31,22 @@ public function __construct()
3331

3432
public function test()
3533
{
36-
// var_dump('控制器目录');
37-
// $os = php_uname('s');
38-
// $controller = 'api/Http/Controllers/Admin';
39-
// $model = 'api/Models';
40-
// $routes = "api/routes";
41-
// $resource = 'api/Http/Resources';
42-
// $api = 'element/src/api';
43-
// $front_model = 'element/src/model';
44-
// $page = 'element/src/view';
45-
// $back_controller_path = app_path($controller);
46-
// $back_model_path = app_path($model);
47-
// $back_routes_path = base_path($routes);
48-
// $back_resources_path = app_path($resource);
49-
// $app_path = app_path();
50-
// if (strpos($os, 'Windows')>=0){
51-
// $back_controller_path = str_replace("\\", "/", $back_controller_path);
52-
// $back_model_path = str_replace("\\", "/", $back_model_path);
53-
// $back_routes_path = str_replace("\\", "/", $back_routes_path);
54-
// $back_resources_path = str_replace("\\", "/", $back_resources_path);
55-
// }
56-
$tableName = 'wechats';
57-
if (Storage::disk('code')->exists($tableName)){
58-
Storage::disk('code')->deleteDirectory($tableName);
59-
}
60-
Storage::disk('code')->makeDirectory($tableName);
61-
Storage::disk('code')->makeDirectory($tableName.'/'.$controller);
62-
Storage::disk('code')->makeDirectory($tableName.'/'.$model);
63-
Storage::disk('code')->makeDirectory($tableName.'/'.$routes);
64-
Storage::disk('code')->makeDirectory($tableName.'/'.$resource);
65-
Storage::disk('code')->makeDirectory($tableName.'/'.$api);
66-
Storage::disk('code')->makeDirectory($tableName.'/'.$front_model);
67-
Storage::disk('code')->makeDirectory($tableName.'/'.$page);
68-
$zip = public_path("code/$tableName.zip");//压缩文件名,自己命名
69-
HZip::zipDir(public_path("code/$tableName"),$zip);
70-
return response()->download($zip, basename($zip))->deleteFileAfterSend(true);
7134

72-
// $code_root_dir = public_path('code/'.'wechats');
73-
// if (!file_exists($code_root_dir)){
74-
// mkdir($code_root_dir);
35+
// $tableName = 'wechats';
36+
// if (Storage::disk('code')->exists($tableName)){
37+
// Storage::disk('code')->deleteDirectory($tableName);
7538
// }
76-
// mkdir($code_root_dir.'/'.$controller);
77-
// mkdir($code_root_dir.'/'.$model);
78-
// mkdir($code_root_dir.'/'.$routes);
79-
// mkdir($code_root_dir.'/'.$resource);
80-
// var_dump($back_controller_path);
81-
// var_dump($back_model_path);
82-
// var_dump($back_routes_path);
83-
// var_dump($back_resources_path);
84-
85-
86-
87 10000 -
88-
89-
39+
// Storage::disk('code')->makeDirectory($tableName);
40+
// Storage::disk('code')->makeDirectory($tableName.'/'.$controller);
41+
// Storage::disk('code')->makeDirectory($tableName.'/'.$model);
42+
// Storage::disk('code')->makeDirectory($tableName.'/'.$routes);
43+
// Storage::disk('code')->makeDirectory($tableName.'/'.$resource);
44+
// Storage::disk('code')->makeDirectory($tableName.'/'.$api);
45+
// Storage::disk('code')->makeDirectory($tableName.'/'.$front_model);
46+
// Storage::disk('code')->makeDirectory($tableName.'/'.$page);
47+
// $zip = public_path("code/$tableName.zip");//压缩文件名,自己命名
48+
// HZip::zipDir(public_path("code/$tableName"),$zip);
49+
// return response()->download($zip, basename($zip))->deleteFileAfterSend(true);
9050

9151
}
9252

@@ -156,6 +116,11 @@ public function bind(){
156116
$address = env('REGISTER_ADDRESS','127.0.0.1:1680');
157117
Gateway::$registerAddress = $address;
158118
Gateway::bindUid($client_id, $uid);
119+
$old_user_id = Gateway::getUidByClientId($client_id);
120+
var_dump($uid);
121+
var_dump($old_user_id);
122+
//
123+
159124
// 获得所有的client_id,删除除了该次登录的内容以外,剔除其他的客户端,前端自动的退出
160125
$arr = Gateway::getClientIdByUid($uid);
161126
// 获得之前登录的所有client_id
@@ -167,6 +132,7 @@ public function bind(){
167132
'select' => 'all',
168133
];
169134
Gateway::sendToAll(json_encode($result), $arr);
135+
return $this->success();
170136
}
171137

172138
/**
@@ -195,6 +161,7 @@ public function logout()
195161
// 取消client_id与uid的绑定
196162
if ($uuid) {
197163
Gateway::unbindUid($uuid, $id);
164+
Gateway::closeClient($uuid);
198165
}
199166
Auth::user()->token()->delete();
200167
// $admin = Auth::user();
Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
<?php
2+
3+
namespace App\Http\Controllers\Admin;
4+
5+
use App\Models\Admin;
6+
use Illuminate\Http\Request;
7+
use App\GatewayClient\Gateway;
8+
use Illuminate\Support\Facades\Auth;
9+
use function React\Promise\all;
10+
11+
class ServiceController extends Controller
12+
{
13+
/**
14+
* Display a listing of the resource.
15+
*
16+
* @return \Illuminate\Http\Response
17+
*/
18+
19+
public function check()
20+
{
21+
/**
22+
* 先检测客服是否已经上班,不上班或者上线无法使用客服功能
23+
* 客服如果已经登记了,做下面的事情:
24+
* 1.则把所有要咨询的用户都存入到一个服务组,便于客服统一给大家发信息
25+
* 2.把自己的信息进行注册,发送给客服,让客服能知道现哪些人已经在线等待咨询
26+
*/
27+
28+
29+
$customer = ENV("CUSTOMER", "admin");
30+
$uid = Admin::where('email', $customer)->value('id');
31+
$address = env('REGISTER_ADDRESS', '127.0.0.1:1680');
32+
Gateway::$registerAddress = $address;
33+
$client_id = request('uuid'); // 获取现在接入的用户
34+
Gateway::joinGroup($client_id, "services"); // 把现在的用户接入到客服组,客户退出等可以同时进行通知
35+
if (Gateway::isUidOnline($uid)) {
36+
// 获得客服对应的client_id,用于发送信息
37+
$arr = Gateway::getClientIdByUid($uid);
38+
if (count($arr) === 1) {
39+
// uid与client_id 一对一,才能找到指定的session,获得是否注册为客服
40+
$customer_client_id = array_pop($arr); // 客服的client_id
41+
$session = Gateway::getSession($customer_client_id);
42+
if (key_exists("is_customer", $session) && $session['is_customer']) {
43+
// 登记用户信息进入组
44+
$user = Auth::user();
45+
$data = [
46+
'name' => $user->email,
47+
'avatar' => $user->avatar,
48+
'client_id' => $client_id,
49+
"type" => 'userLogin',
50+
'content' => null,
51+
'select' => 'all'
52+
];
53+
Gateway::sendToClient($customer_client_id, json_encode($data));
54+
return $this->successWithInfo("已经有客服存在");
55+
} else {
56+
return $this->errorWithInfo('客服在线但没有登录客服页面,请稍后', 400);
57+
}
58+
} else {
59+
return $this->error();
60+
}
61+
} else {
62+
return $this->errorWithInfo("客服已经下班,无法咨询。", 400);
63+
}
64+
}
65+
66+
public function leave()
67+
{
68+
/**
69+
* 客户离开,则我们进行相应的处理
70+
* 1.退出组
71+
* 2.提示客服,某个用户已经下线
72+
*/
73+
// 退出组
74+
$address = env('REGISTER_ADDRESS', '127.0.0.1:1680');
75+
Gateway::$registerAddress = $address;
76+
$client_id = $this->getWebsocketClientId(); // 获取现在接入的用户
77+
Gateway::leaveGroup($client_id, "services"); // 把现在的用户接入到客服组,用户对退出等进行通知
78+
// 提醒客服,我已经退出
79+
$customer_client_id = $this->getCustomerClientId();
80+
$data = [
81+
'client_id' => $client_id,
82+
"type" => 'userLogout',
83+
'content' => null,
84+
'select' => 'all'
85+
];
86+
Gateway::sendToClient($customer_client_id, json_encode($data));
87+
return $this->success();
88+
}
89+
90+
protected function getCustomerClientId()
91+
{
92+
$customer = ENV("CUSTOMER", "admin");
93+
$uid = Admin::where('email', $customer)->value('id');
94+
$arr = Gateway::getClientIdByUid($uid);
95+
// uid与client_id 一对一,才能找到指定的session,获得是否注册为客服
96+
$customer_client_id = array_pop($arr); // 客服的client_id
97+
return $customer_client_id;
98+
}
99+
100+
protected function initGateWay()
101+
{
102+
$address = env('REGISTER_ADDRESS', '127.0.0.1:1680');
103+
Gateway::$registerAddress = $address;
104+
}
105+
106+
public function customer()
107+
{
108+
$customer = ENV("CUSTOMER", "admin");
109+
return $this->successWithData([
110+
"customer" => $customer
111+
]);
112+
}
113+
114+
// 客服在线注册
115+
public function register()
116+
{
117+
// 在client_id 对应的session中登记为客服,因为用户即使在线,有时候也没有打开这个页面
118+
// 所以不一定是客户,这就要求用户进入到页面后,会自动的注册登记
119+
$uid = Auth::id();
120+
$address = env('REGISTER_ADDRESS', '127.0.0.1:1680');
121+
Gateway::$registerAddress = $address;
122+
if (Gateway::isUidOnline($uid)) {
123+
$arr = Gateway::getClientIdByUid($uid);
124+
$client_id = $arr[0];
125+
Gateway::updateSession($client_id, [
126+
'is_customer' => true
127+
]);
128+
$data = [
129+
'type' => "customerLogin",
130+
'select' => "all",
131+
"name" => Auth::user()->email
132+
];
133+
Gateway::sendToGroup("services", json_encode($data));
134+
return $this->success();
135+
} else {
136+
return $this->errorWithInfo("客服注册失败。");
137+
}
138+
139+
}
140+
141+
public function unRegister()
142+
{
143+
// 客服取消注册在线
144+
// 前端退出页面的时候,取消客服注册
145+
146+
$client_id = request('uuid');
147+
$address = env('REGISTER_ADDRESS', '127.0.0.1:1680');
148+
Gateway::$registerAddress = $address;
149+
Gateway::updateSession($client_id, [
150+
'is_customer' => false
151+
]);
152+
$data = [
153+
'type' => "customerLogout",
154+
'select' => "all"
155+
];
156+
Gateway::sendToGroup("services", json_encode($data));
157+
return $this->success();
158+
}
159+
// 普通用户发送数据给客服
160+
public function sendDataToCustomer()
161+
{
162+
$data = request()->only(['name', 'content', 'time']);
163+
$this->initGateWay();
164+
$client_id = $this->getWebsocketClientId();
165+
$customer_client_id = $this->getCustomerClientId();
166+
$admin_id = (int)Gateway::getUidByClientId($client_id);
167+
$customer_admin_id = (int)Gateway::getUidByClientId($customer_client_id);
168+
$data["select"] = "all";
169+
$data["type"] = "userSay";
170+
Gateway::sendToClient($customer_client_id, json_encode($data));
171+
return $this->success();
172+
173+
}
174+
// 客服发送数据给用户
175+
public function sendDataToUser()
176+
{
177+
$data = request()->only(['name', 'content', 'time', 'avatar']);
178+
$client_id = request('client_id');
179+
$this->initGateWay();
180+
$data["select"] = "all";
181+
$data["type"] = "customerSay";
182+
Gateway::sendToClient($client_id, json_encode($data));
183+
return $this->success();
184+
185+
}
186+
187+
public function index()
188+
{
189+
//
190+
}
191+
192+
/**
193+
* Store a newly created resource in storage.
194+
*
195+
* @param \Illuminate\Http\Request $request
196+
* @return \Illuminate\Http\Response
197+
*/
198+
public function store(Request $request)
199+
{
200+
//
201+
}
202+
203+
/**
204+
* Display the specified resource.
205+
*
206+
* @param int $id
207+
* @return \Illuminate\Http\Response
208+
*/
209+
public function show($id)
210+
{
211+
//
212+
}
213+
214+
/**
215+
* Update the specified resource in storage.
216+
*
217+
* @param \Illuminate\Http\Request $request
218+
* @param int $id
219+
* @return \Illuminate\Http\Response
220+
*/
221+
public function update(Request $request, $id)
222+
{
223+
//
224+
}
225+
226+
/**
227+
* Remove the specified resource from storage.
228+
*
229+
* @param int $id
230+
* @return \Illuminate\Http\Response
231+
*/
232+
public function destroy($id)
233+
{
234+
//
235+
}
236+
}

api/app/Http/Controllers/Admin/Tool.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ protected function successWithInfo($msg = '操作成功', $code = 200)
2525
], $code);
2626
}
2727

28+
29+
protected function getWebsocketClientId()
30+
{
31+
return request()->header('X-Socket-Id');
32+
}
33+
2834
protected function successWithData($data = [], $code = 200)
2935
{
3036
return response()->json([

api/routes/api.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@
3939
Route::middleware(['auth:admin'])->prefix('admin')->namespace('Admin')->group(function(){
4040
Route::get('tables/list', 'TableController@getAllTable')->name("tables.list");
4141
Route::get('table_configs/columns', 'TableConfigController@getColumnByTable')->name("tables.column");
42+
Route::post('services/check','ServiceController@check')->name("services.check");
43+
Route::post('services/register','ServiceController@register')->name("services.register");
44+
Route::post('services/un_register','ServiceController@unRegister')->name("services.un_register");
45+
Route::get('services/customer', 'ServiceController@customer')->name("services.customer");
46+
Route::post('services/user_leave', 'ServiceController@leave')->name("services.leave");
47+
Route::post('services/send_data_to_customer', 'ServiceController@sendDataToCustomer')->name("services.send_data_to_customer");
48+
Route::post('services/send_data_to_user', 'ServiceController@sendDataToUser')->name("services.send_data_to_user");
4249
});
4350

4451

@@ -120,4 +127,4 @@
120127
});
121128
Route::middleware(['auth:admin','role'])->prefix('admin')->namespace('Admin')->group(function(){
122129
Route::apiResource('wechats', 'WechatController');
123-
});
130+
});

0 commit comments

Comments
 (0)
0