Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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-
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)

AltStyle によって変換されたページ (->オリジナル) /