完成群呼队列管理功能
This commit is contained in:
parent
38ce9407cd
commit
e89372b761
|
|
@ -14,6 +14,7 @@ use App\Models\Role;
|
|||
use App\Models\Sip;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Redis;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
|
@ -263,7 +264,6 @@ class ApiController extends Controller
|
|||
|
||||
}
|
||||
|
||||
|
||||
public function payList(Request $request)
|
||||
{
|
||||
$id = $request->input('id');
|
||||
|
|
@ -271,4 +271,19 @@ class ApiController extends Controller
|
|||
return $this->success('ok',['list'=>$res->items(),'lastPage'=>$res->lastPage()]);
|
||||
}
|
||||
|
||||
public function getSipsByQueueId(Request $request)
|
||||
{
|
||||
$queueId = $request->input('queue_id');
|
||||
$lists = Sip::with('user')->get();
|
||||
$values = [];
|
||||
if ($queueId){
|
||||
$values = DB::table('queue_sip')->where('queue_id',$queueId)->pluck('sip_id')->toArray();
|
||||
}
|
||||
foreach ($lists as $item){
|
||||
$item->checked = in_array($item->id,$values) ? true : false;
|
||||
}
|
||||
return $this->success('ok',['lists'=>$lists,'values'=>$values]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,127 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Callcenter;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use GuzzleHttp\Client;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use App\Models\Queue;
|
||||
|
||||
class QueueController extends Controller
|
||||
{
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
if ($request->ajax()){
|
||||
$res = Queue::withCount('sips')->orderByDesc('id')->paginate($request->input('limit',30));
|
||||
return $this->success('ok',$res->items(),$res->total());
|
||||
}
|
||||
return View::make('callcenter.queue.index');
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
return View::make('callcenter.queue.create');
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
$data = $request->all([
|
||||
'name',
|
||||
'strategy',
|
||||
'max_wait_time',
|
||||
'sips',
|
||||
]);
|
||||
$data['sips'] = $data['sips'] ? explode(',',$data['sips']) : [];
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
$queueId = DB::table('queue')->insertGetId([
|
||||
'name' => $data['name'],
|
||||
'strategy' => $data['strategy'],
|
||||
'max_wait_time' => $data['max_wait_time'],
|
||||
]);
|
||||
foreach ($data['sips'] as $sipId){
|
||||
DB::table('queue_sip')->insert([
|
||||
'queue_id' => $queueId,
|
||||
'sip_id' => $sipId,
|
||||
]);
|
||||
}
|
||||
DB::commit();
|
||||
return $this->success();
|
||||
}catch (\Exception $exception){
|
||||
DB::rollBack();
|
||||
Log::error('添加队列异常:'.$exception->getMessage());
|
||||
return $this->error();
|
||||
}
|
||||
}
|
||||
|
||||
public function edit($id)
|
||||
{
|
||||
$model = Queue::query()->where('id',$id)->first();
|
||||
return View::make('callcenter.queue.edit',compact('model'));
|
||||
}
|
||||
|
||||
public function update(Request $request,$id)
|
||||
{
|
||||
$model = Queue::query()->where('id',$id)->first();
|
||||
$data = $request->all([
|
||||
'name',
|
||||
'strategy',
|
||||
'max_wait_time',
|
||||
]);
|
||||
$sipids = $request->input('sips') ? explode(',',$request->input('sips')) : [];
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
$model->update($data);
|
||||
$model->sips()->sync($sipids);
|
||||
DB::commit();
|
||||
return $this->success();
|
||||
}catch (\Exception $exception){
|
||||
DB::rollBack();
|
||||
Log::error('更新队列异常:'.$exception->getMessage());
|
||||
return $this->error();
|
||||
}
|
||||
}
|
||||
|
||||
public function destroy(Request $request)
|
||||
{
|
||||
$ids = $request->get('ids');
|
||||
if (empty($ids)){
|
||||
return $this->error('请选择删除项');
|
||||
}
|
||||
DB::beginTransaction();
|
||||
try{
|
||||
DB::table('queue_sip')->whereIn('queue_id',$ids)->delete();
|
||||
DB::table('queue')->whereIn('id',$ids)->delete();
|
||||
DB::commit();
|
||||
return $this->success();
|
||||
}catch (\Exception $exception){
|
||||
DB::rollBack();
|
||||
Log::error('删除队列异常:'.$exception->getMessage());
|
||||
return $this->error();
|
||||
}
|
||||
}
|
||||
|
||||
public function updateXml()
|
||||
{
|
||||
$queues = Queue::with('sips')->get()->toArray();
|
||||
try{
|
||||
$client = new Client();
|
||||
$client->post(config('freeswitch.swoole_http_url.callcenter'),
|
||||
[
|
||||
'json' => $queues,
|
||||
'timeout' => 30
|
||||
]
|
||||
);
|
||||
return $this->success();
|
||||
}catch (\Exception $exception){
|
||||
Log::error('更新群呼配置异常:' . $exception->getMessage());
|
||||
return $this->error('更新失败');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Callcenter;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class Task extends Controller
|
||||
{
|
||||
//
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
class Queue extends Model
|
||||
{
|
||||
protected $table = 'queue';
|
||||
protected $guarded = ['id'];
|
||||
protected $appends = ['strategy_name'];
|
||||
|
||||
public function sips()
|
||||
{
|
||||
return $this->belongsToMany(Sip::class,'queue_sip');
|
||||
}
|
||||
|
||||
public function getStrategyNameAttribute()
|
||||
{
|
||||
return $this->attributes['strategy_name'] = Arr::get(config('freeswitch.strategy'),$this->strategy);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -34,7 +34,7 @@ class Sip extends Model
|
|||
*/
|
||||
public function user()
|
||||
{
|
||||
return $this->hasOne('App\Models\User','sip_id','id')->withDefault(['nickname'=>'-']);
|
||||
return $this->hasOne('App\Models\User','sip_id','id')->withDefault(['nickname'=>'未分配']);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,5 +6,6 @@ use Illuminate\Database\Eloquent\Model;
|
|||
|
||||
class Task extends Model
|
||||
{
|
||||
//
|
||||
protected $table = 'task';
|
||||
protected $guarded = ['id'];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,6 +99,25 @@ class MenuTableSeeder extends Seeder
|
|||
],
|
||||
]
|
||||
],
|
||||
[
|
||||
'name' => '群呼管理',
|
||||
'route' => null,
|
||||
'url' => null,
|
||||
'icon' => 'layui-icon-group',
|
||||
'type' => 2,
|
||||
'sort' => 2,
|
||||
'permission_name' => 'callcenter',
|
||||
'child' => [
|
||||
[
|
||||
'name' => '队列管理',
|
||||
'route' => 'callcenter.queue',
|
||||
'url' => null,
|
||||
'icon' => 'layui-icon-user',
|
||||
'type' => 1,
|
||||
'permission_name' => 'callcenter.queue',
|
||||
],
|
||||
]
|
||||
],
|
||||
[
|
||||
'name' => '实时聊天',
|
||||
'route' => null,
|
||||
|
|
|
|||
|
|
@ -123,6 +123,22 @@ class UserTableSeeder extends Seeder
|
|||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'name' => 'callcenter',
|
||||
'display_name' => '群呼管理',
|
||||
'child' => [
|
||||
[
|
||||
'name' => 'callcenter.queue',
|
||||
'display_name' => '队列管理',
|
||||
'child' => [
|
||||
['name' => 'callcenter.queue.create', 'display_name' => '添加'],
|
||||
['name' => 'callcenter.queue.edit', 'display_name' => '编辑'],
|
||||
['name' => 'callcenter.queue.destroy', 'display_name' => '删除'],
|
||||
['name' => 'callcenter.queue.updateXml', 'display_name' => '更新配置'],
|
||||
]
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'name' => 'crm',
|
||||
'display_name' => 'CRM管理',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
{{csrf_field()}}
|
||||
<div class="layui-form-item">
|
||||
<label for="" class="layui-form-label">队列名称</label>
|
||||
<div class="layui-input-block">
|
||||
<input class="layui-input" type="text" name="name" lay-verify="required" value="{{$model->name??old('name')}}" placeholder="如:队列一">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label for="" class="layui-form-label">振铃策略</label>
|
||||
<div class="layui-input-block">
|
||||
<select name="strategy" >
|
||||
@foreach(config('freeswitch.strategy') as $k => $v)
|
||||
<option value="{{$k}}">{{$v}}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label for="" class="layui-form-label">超时时间</label>
|
||||
<div class="layui-input-inline">
|
||||
<input class="layui-input" type="text" maxlength="4" name="max_wait_time" lay-verify="required|number" value="{{$model->max_wait_time??0}}" placeholder="">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">最大等待时间,0为一直等待</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label for="" class="layui-form-label">分配坐席</label>
|
||||
<div class="layui-input-block">
|
||||
@include('common.get_sips_by_queue_id',['queue_id'=>$model->id??0])
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button type="button" class="layui-btn layui-btn-sm" lay-submit lay-filter="go-close-refresh" >确认</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
@extends('base')
|
||||
|
||||
@section('content')
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body">
|
||||
<form action="{{route('callcenter.queue.store')}}" method="post" class="layui-form">
|
||||
@include('callcenter.queue._form')
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
@extends('base')
|
||||
|
||||
@section('content')
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body">
|
||||
<form action="{{route('callcenter.queue.update',['id'=>$model->id])}}" method="post" class="layui-form">
|
||||
{{method_field('put')}}
|
||||
@include('callcenter.queue._form')
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
@extends('base')
|
||||
|
||||
@section('content')
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header layuiadmin-card-header-auto">
|
||||
<form class="layui-form">
|
||||
<div class="layui-btn-group">
|
||||
@can('callcenter.queue.destroy')
|
||||
<button class="layui-btn layui-btn-sm layui-btn-danger" type="button" id="listDelete" data-url="{{route('callcenter.queue.destroy')}}">删除</button>
|
||||
@endcan
|
||||
@can('callcenter.queue.create')
|
||||
<button type="button" class="layui-btn layui-btn-sm" id="addBtn">添加</button>
|
||||
@endcan
|
||||
@can('callcenter.queue.updateXml')
|
||||
<button class="layui-btn layui-btn-sm" type="button" id="updateXml">更新配置</button>
|
||||
@endcan
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="layui-card-body">
|
||||
<table id="dataTable" lay-filter="dataTable"></table>
|
||||
<script type="text/html" id="options">
|
||||
<div class="layui-btn-group">
|
||||
@can('callcenter.queue.edit')
|
||||
<a class="layui-btn layui-btn-sm" lay-event="edit">编辑</a>
|
||||
@endcan
|
||||
</div>
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@section('script')
|
||||
<script>
|
||||
layui.use(['layer','table','form','jquery'],function () {
|
||||
var $ = layui.jquery;
|
||||
var layer = layui.layer;
|
||||
var form = layui.form;
|
||||
var table = layui.table;
|
||||
//用户表格初始化
|
||||
var dataTable = table.render({
|
||||
elem: '#dataTable'
|
||||
,height: 'full-200'
|
||||
,url: "{{ route('callcenter.queue') }}" //数据接口
|
||||
,page: true //开启分页
|
||||
,cols: [[ //表头
|
||||
{checkbox: true}
|
||||
,{field: 'id', title: 'ID', sort: true,width:80}
|
||||
,{field: 'name', title: '队列名称'}
|
||||
,{field: 'strategy_name', title: '振铃策略'}
|
||||
,{field: 'sips_count', title: '坐席数量'}
|
||||
,{field: 'max_wait_time', title: '超时时间(秒)'}
|
||||
,{field: 'created_at', title: '添加时间'}
|
||||
,{ width: 220, align:'center', toolbar: '#options', title:'操作'}
|
||||
]]
|
||||
});
|
||||
|
||||
//监听工具条
|
||||
table.on('tool(dataTable)', function(obj){ //注:tool是工具条事件名,dataTable是table原始容器的属性 lay-filter="对应的值"
|
||||
var data = obj.data //获得当前行数据
|
||||
,layEvent = obj.event; //获得 lay-event 对应的值
|
||||
if(layEvent === 'del'){
|
||||
deleteData(obj,"{{ route('callcenter.queue.destroy') }}");
|
||||
} else if(layEvent === 'edit'){
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: "编辑",
|
||||
shadeClose: true,
|
||||
area: ["800px","600px"],
|
||||
content: '/callcenter/queue/'+data.id+'/edit',
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
$("#addBtn").click(function () {
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: "添加",
|
||||
shadeClose: true,
|
||||
area: ["800px","600px"],
|
||||
content: '/callcenter/queue/create',
|
||||
})
|
||||
})
|
||||
|
||||
//更新配置
|
||||
$("#updateXml").click(function () {
|
||||
layer.confirm('确认更新配置吗?', function (index) {
|
||||
layer.close(index);
|
||||
var load = layer.load();
|
||||
$.post("{{ route('callcenter.queue.updateXml') }}", {}, function (res) {
|
||||
layer.close(load);
|
||||
layer.msg(res.msg, {icon: res.code === 0 ? 1 : 2})
|
||||
});
|
||||
})
|
||||
})
|
||||
})
|
||||
</script>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
<div id="transfer-sips"></div>
|
||||
<input type="hidden" name="sips" id="sips">
|
||||
<script>
|
||||
layui.use(['jquery','form', 'layer','transfer'], function () {
|
||||
var $ = layui.jquery;
|
||||
var form = layui.form;
|
||||
var layer = layui.layer;
|
||||
var transfer = layui.transfer;
|
||||
// 一般来说,权限数据是异步传递过来的
|
||||
$.ajax({
|
||||
method: 'post',
|
||||
url: '/api/get_sips_by_queue_id?queue_id={{$queue_id}}',
|
||||
dataType: 'json',
|
||||
success: function (res) {
|
||||
transfer.render({
|
||||
elem: '#transfer-sips'
|
||||
,id:'transfer-sips'
|
||||
,title: ['所有坐席', '已选坐席']
|
||||
,parseData: function(item){
|
||||
return {
|
||||
"value": item.id //数据值
|
||||
,"title": item.username + "(" + item.user.nickname + ")" //数据标题
|
||||
//,"disabled": res.disabled //是否禁用
|
||||
,"checked": res.checked //是否选中
|
||||
}
|
||||
}
|
||||
,data: res.data.lists
|
||||
,height: 300
|
||||
,value: res.data.values
|
||||
,onchange: function(data, index){
|
||||
var ids = []
|
||||
getData = transfer.getData('transfer-sips');
|
||||
for (var v of getData){
|
||||
ids.push(v.value)
|
||||
}
|
||||
$("#sips").val(ids.join(','))
|
||||
}
|
||||
})
|
||||
$("#sips").val(res.data.values.join(','))
|
||||
|
||||
},
|
||||
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
|
@ -19,6 +19,7 @@ Route::middleware('auth:api')->get('/user', function (Request $request) {
|
|||
|
||||
Route::post('get_permission_by_role_id','ApiController@getPermissionByRoleId')->name('api.getPermissionByRoleId');
|
||||
Route::post('get_role_by_user_id','ApiController@getRoleByUserId')->name('api.getRoleByUserId');
|
||||
Route::post('get_sips_by_queue_id','ApiController@getSipsByQueueId')->name('api.getSipsByQueueId');
|
||||
Route::post('get_department_by_user_id','ApiController@getDepartmentByUserId')->name('api.getDepartmentByUserId');
|
||||
Route::post('get_user','ApiController@getUser')->name('api.getUser');
|
||||
Route::post('get_node','ApiController@getNode')->name('api.getNode');
|
||||
|
|
|
|||
|
|
@ -189,6 +189,30 @@ Route::group(['prefix'=>'call','namespace'=> 'Call','middleware'=>['auth','permi
|
|||
|
||||
});
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| 群呼模块
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
Route::group(['prefix'=>'callcenter','namespace'=>'Callcenter','middleware'=>['auth','permission:callcenter']],function () {
|
||||
|
||||
//队列管理
|
||||
Route::group([],function (){
|
||||
Route::get('queue','QueueController@index')->name('callcenter.queue')->middleware('permission:callcenter.queue');
|
||||
//添加
|
||||
Route::get('queue/create','QueueController@create')->name('callcenter.queue.create')->middleware('permission:callcenter.queue.create');
|
||||
Route::post('queue/store','QueueController@store')->name('callcenter.queue.store')->middleware('permission:callcenter.queue.create');
|
||||
//编辑
|
||||
Route::get('queue/{id}/edit','QueueController@edit')->name('callcenter.queue.edit')->middleware('permission:callcenter.queue.edit');
|
||||
Route::put('queue/{id}/update','QueueController@update')->name('callcenter.queue.update')->middleware('permission:callcenter.queue.edit');
|
||||
//删除
|
||||
Route::delete('queue/destroy','QueueController@destroy')->name('callcenter.queue.destroy')->middleware('permission:callcenter.queue.destroy');
|
||||
//更新配置
|
||||
Route::post('queue/updateXml','QueueController@updateXml')->name('callcenter.queue.updateXml')->middleware('permission:callcenter.queue.updateXml');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Reference in New Issue