sth
This commit is contained in:
parent
df63a6c89f
commit
b0739941af
|
|
@ -58,7 +58,7 @@ class Aftersale extends Backend
|
||||||
if ($this->request->isAjax()) {
|
if ($this->request->isAjax()) {
|
||||||
|
|
||||||
$from = $this->request->param('from',1);
|
$from = $this->request->param('from',1);
|
||||||
$dispatch_admin_id = $this->request->param('dispatch_admin_id');
|
$man_id = $this->request->param('man_id');
|
||||||
|
|
||||||
//如果发送的来源是Selectpage,则转发到Selectpage
|
//如果发送的来源是Selectpage,则转发到Selectpage
|
||||||
if ($this->request->request('keyField')) {
|
if ($this->request->request('keyField')) {
|
||||||
|
|
@ -73,9 +73,16 @@ class Aftersale extends Backend
|
||||||
if($from == 2){
|
if($from == 2){
|
||||||
//$builder->where('refund_amount','>',0);
|
//$builder->where('refund_amount','>',0);
|
||||||
//$builder->where('status','<>',-1);
|
//$builder->where('status','<>',-1);
|
||||||
$builder->where('fa_aftersale.dispatch_admin_id',$dispatch_admin_id ?: 0);
|
$builder->where('fa_aftersale.dispatch_admin_id',$man_id ?: 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($from == 3){
|
||||||
|
//$builder->where('refund_amount','>',0);
|
||||||
|
//$builder->where('status','<>',-1);
|
||||||
|
$builder->where('fa_aftersale.worker_id',$man_id ?: 0);
|
||||||
|
}
|
||||||
|
|
||||||
$list = $builder->order($sort, $order)
|
$list = $builder->order($sort, $order)
|
||||||
->paginate($limit);
|
->paginate($limit);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,10 @@ use app\admin\model\Admin;
|
||||||
use app\admin\model\Aftersale;
|
use app\admin\model\Aftersale;
|
||||||
use app\admin\model\Order;
|
use app\admin\model\Order;
|
||||||
use app\admin\model\OrderDispatch;
|
use app\admin\model\OrderDispatch;
|
||||||
|
use app\admin\model\OrderReview;
|
||||||
use app\common\controller\Backend;
|
use app\common\controller\Backend;
|
||||||
|
use PDOStatement;
|
||||||
|
use think\Collection;
|
||||||
use think\Exception;
|
use think\Exception;
|
||||||
use think\exception\DbException;
|
use think\exception\DbException;
|
||||||
use think\response\Json;
|
use think\response\Json;
|
||||||
|
|
@ -108,126 +111,140 @@ class Worker extends Backend
|
||||||
if ($this->request->request('keyField')) {
|
if ($this->request->request('keyField')) {
|
||||||
return $this->selectpage();
|
return $this->selectpage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//派单表
|
||||||
|
$dispatchSubsql = $this->dispatchSubsql();
|
||||||
|
//订单表
|
||||||
|
$orderSubsql = $this->oderSubsql();
|
||||||
|
//评分表
|
||||||
|
$viewSubsql = OrderReview::where('worker_star',5)->field(['worker_id','count(*) as good_count'])->group('worker_id')->buildSql();
|
||||||
|
|
||||||
[$where, $sort, $order, $offset, $limit] = $this->buildparams();
|
[$where, $sort, $order, $offset, $limit] = $this->buildparams();
|
||||||
$list = $this->model
|
$list = $this->model->alias('fa_worker')
|
||||||
|
->with(['area'])
|
||||||
|
->field([
|
||||||
|
'fa_worker.*',
|
||||||
|
'IFNULL(a.dispatch_count, 0) AS dispatch_count',
|
||||||
|
'IFNULL(a.get_count, 0) AS get_count',
|
||||||
|
'IFNULL(a.refuse_count, 0) AS refuse_count',
|
||||||
|
'IFNULL(a.arrive_count, 0) AS arrive_count',
|
||||||
|
'IFNULL(a.avg_time_diff, 0) AS avg_time_diff',
|
||||||
|
'IFNULL(b.finish_num, 0) AS finish_num',
|
||||||
|
'IFNULL(b.total, 0) AS total',
|
||||||
|
'IFNULL(b.performance, 0) AS performance',
|
||||||
|
'IFNULL(b.refund_total, 0) AS refund_total',
|
||||||
|
'IFNULL(b.refund_count, 0) AS refund_count',
|
||||||
|
'IFNULL(b.cost, 0) AS cost',
|
||||||
|
'IFNULL(c.good_count, 0) AS good_count'
|
||||||
|
])
|
||||||
|
->join([$dispatchSubsql => 'a'], 'fa_worker.id = a.worker_id', 'LEFT')
|
||||||
|
->join([$orderSubsql => 'b'], 'fa_worker.id = b.worker_id', 'LEFT')
|
||||||
|
->join([$viewSubsql => 'c'], 'fa_worker.id = c.worker_id', 'LEFT')
|
||||||
->where($where)
|
->where($where)
|
||||||
->order($sort, $order)
|
->order($sort, $order)
|
||||||
->paginate($limit);
|
->paginate($limit);
|
||||||
|
|
||||||
|
$this->_toList($list);
|
||||||
$result = ['total' => $list->total(), 'rows' => $list->items()];
|
$result = ['total' => $list->total(), 'rows' => $list->items()];
|
||||||
return json($result);
|
return json($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool|PDOStatement|string|Collection
|
||||||
|
* @throws DbException
|
||||||
|
*/
|
||||||
|
public function dispatchSubsql(): Collection|bool|string|PDOStatement
|
||||||
|
{
|
||||||
|
$builder = new OrderDispatch();
|
||||||
|
$fields = [
|
||||||
|
'worker_id',
|
||||||
|
"COUNT(*) AS dispatch_count", //分配数
|
||||||
|
"COUNT(CASE WHEN status NOT IN (0, -10) THEN 1 END) AS get_count", //接单数
|
||||||
|
//"COUNT(CASE WHEN status IN (60) THEN 1 END) AS finish_count", //完成数
|
||||||
|
"COUNT(CASE WHEN status NOT IN (-10) THEN 1 END) AS refuse_count", //拒绝数
|
||||||
|
"COUNT(arrive_time) AS arrive_count", //上门数
|
||||||
|
"AVG(CASE WHEN status = 60 AND arrive_time IS NOT NULL THEN UNIX_TIMESTAMP(arrive_time) - UNIX_TIMESTAMP(create_time) END) AS avg_time_diff", //联系时效
|
||||||
|
];
|
||||||
|
$builder->field($fields);
|
||||||
|
$builder->group('worker_id');
|
||||||
|
return $builder->buildSql();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//图表统计
|
//图表统计
|
||||||
public function chart($filter,$getAll=false){
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws DbException
|
||||||
|
*/
|
||||||
$orderValid = implode(',',$this->model->tabStatus(Order::TAB_VALID));
|
public function oderSubsql()
|
||||||
|
{
|
||||||
|
$orderValid = implode(',',(new Order())->tabStatus(Order::TAB_VALID));
|
||||||
|
|
||||||
//"COUNT(CASE WHEN status IN (".$orderValid.") THEN 1 END) AS ing_num",
|
//"COUNT(CASE WHEN status IN (".$orderValid.") THEN 1 END) AS ing_num",
|
||||||
$fields = [
|
$fields = [
|
||||||
'dispatch_admin_id',
|
'worker_id',
|
||||||
"COUNT(CASE WHEN status = 60 THEN 1 END) AS finish_num", //完成数
|
"COUNT(CASE WHEN status = 60 THEN 1 END) AS finish_num", //完成数
|
||||||
"COUNT(CASE WHEN status IN (".$orderValid.") THEN 1 END) AS count_num", //总订单数 (排除取消 和草稿)
|
//"COUNT(CASE WHEN status IN (".$orderValid.") THEN 1 END) AS count_num", //总订单数 (排除取消 和草稿)
|
||||||
"SUM(CASE WHEN status = 60 THEN total END) AS total", //成效额
|
"SUM(CASE WHEN status = 60 THEN total END) AS total", //成效额
|
||||||
"SUM(CASE WHEN status = 60 THEN performance END) AS performance", //业绩
|
"SUM(CASE WHEN status = 60 THEN performance END) AS performance", //业绩
|
||||||
|
"SUM(CASE WHEN status = 60 THEN cost END) AS cost", //成效额
|
||||||
|
|
||||||
"SUM(CASE WHEN status = 60 THEN (cost + material_cost) END) AS cost_total", //总成本
|
// "SUM(CASE WHEN status = 60 THEN (cost + material_cost) END) AS cost_total", //总成本
|
||||||
|
|
||||||
"SUM(CASE WHEN status = 60 THEN (refund_amount + worker_refund_amount) END) AS refund_total", //退款总数
|
"SUM(CASE WHEN status = 60 THEN (refund_amount + worker_refund_amount) END) AS refund_total", //退款总数
|
||||||
"COUNT(CASE WHEN refund_amount > 0 OR worker_refund_amount > 0 THEN 1 END) AS refund_count", //退款订单数量
|
"COUNT(CASE WHEN refund_amount > 0 OR worker_refund_amount > 0 THEN 1 END) AS refund_count", //退款订单数量
|
||||||
"AVG(CASE WHEN status > 10 THEN UNIX_TIMESTAMP(dispatch_time) - UNIX_TIMESTAMP(create_time) END) AS avg_time_diff", //派单时效
|
//"AVG(CASE WHEN status > 10 THEN UNIX_TIMESTAMP(dispatch_time) - UNIX_TIMESTAMP(create_time) END) AS avg_time_diff", //派单时效
|
||||||
// "SUM(CASE WHEN status = 60 THEN (field1 + field2) END) AS performance",
|
// "SUM(CASE WHEN status = 60 THEN (field1 + field2) END) AS performance",
|
||||||
];
|
];
|
||||||
|
|
||||||
$builder = $this->model
|
$builder = (new Order())->field($fields);
|
||||||
->field($fields);
|
|
||||||
//->where('dispatch_admin_id','>',0);
|
//->where('dispatch_admin_id','>',0);
|
||||||
|
return $builder->group('worker_id')->buildSql();
|
||||||
|
|
||||||
if(!empty($filter['admin_id'])){
|
|
||||||
$builder->where('dispatch_admin_id',$filter['admin_id']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!empty($filter['start_time']) && !empty($filter['end_time'])){
|
|
||||||
$time_by = $filter['time_by'] ??1;
|
|
||||||
if($time_by == 1){ //按派单时间
|
|
||||||
$time_field = 'dispatch_time';
|
|
||||||
}else{ //按录单时间
|
|
||||||
$time_field = 'create_time';
|
|
||||||
}
|
|
||||||
$builder->whereBetween($time_field,[$filter['start_time'],$filter['end_time']]);
|
|
||||||
}
|
|
||||||
//城市
|
|
||||||
if(!empty($filter['area_id'])){
|
|
||||||
$builder->where('area_id',$filter['area_id']);
|
|
||||||
}
|
|
||||||
//项目
|
|
||||||
if(!empty($filter['item_id'])){
|
|
||||||
$builder->where('item_id',$filter['item_id']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if($getAll){
|
|
||||||
$data = $builder->group('dispatch_admin_id')->limit(50)->select();
|
|
||||||
}else{
|
|
||||||
$data = $builder->group('dispatch_admin_id')->paginate();
|
|
||||||
}
|
|
||||||
|
|
||||||
$newData = [];
|
|
||||||
|
|
||||||
if(!empty($data)){
|
|
||||||
foreach ($data as &$datum){
|
|
||||||
//利润率 = 总业绩/总成效额
|
|
||||||
$datum->performance_rate = $this->_calc($datum->performance,$datum->total,4,true);
|
|
||||||
//转化率 = 完单数 / 总订单数
|
|
||||||
$datum->trans_rate = $this->_calc($datum->finish_num,$datum->count_num,4,true);
|
|
||||||
//变现值 = 总业绩 / 总订单数
|
|
||||||
$datum->cash_value = $this->_calc($datum->performance,$datum->count_num,2);
|
|
||||||
//客单利润 = 总利润 / 完单数
|
|
||||||
$datum->performance_avg = $this->_calc($datum->performance,$datum->finish_num,2);
|
|
||||||
//客单价 = 总成效额 / 完单数
|
|
||||||
$datum->total_avg = $this->_calc($datum->total,$datum->finish_num,2);
|
|
||||||
|
|
||||||
if(!empty($datum->dispatch_admin_id)){
|
|
||||||
$datum->admin_user = Admin::where($datum->dispatch_admin_id)->value('nickname')??'系统';
|
|
||||||
}else{
|
|
||||||
$datum->admin_user = '系统';
|
|
||||||
}
|
|
||||||
$datum->avg_time_diff = $this->_calc($datum->avg_time_diff,3600*24,2);
|
|
||||||
|
|
||||||
$datum->id = $datum->dispatch_admin_id;
|
|
||||||
$newData[] = $datum->toArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if($getAll){
|
|
||||||
return $newData;
|
|
||||||
}else{
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
//dump($newData);exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $a
|
* @param $a
|
||||||
* @param $b
|
* @param $b
|
||||||
* @param $scale
|
* @param int $scale
|
||||||
|
* @param bool $is_percent
|
||||||
* @return int|string
|
* @return int|string
|
||||||
*/
|
*/
|
||||||
private function _calc($a,$b,$scale=4,$is_percent=false){
|
private function _calc($a, $b, int $scale=4, bool $is_percent=false): int|string
|
||||||
$val = $b > 0 ? bcdiv($a,$b,$scale) : 0;
|
{
|
||||||
|
$a = $a??0;
|
||||||
|
$b = $b??0;
|
||||||
|
$val = $b > 0 ? bcdiv($a,$b,$scale) : '0.00';
|
||||||
|
|
||||||
if($is_percent){
|
if($is_percent){
|
||||||
|
|
||||||
return bcmul($val,100,2);
|
return bcmul($val,100,2);
|
||||||
}
|
}
|
||||||
return $val;
|
return $val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function _toList(\think\Paginator $list)
|
||||||
|
{
|
||||||
|
foreach ($list as &$datum){
|
||||||
|
//利润率 = 总业绩/总成效额
|
||||||
|
$datum->performance_rate = $this->_calc($datum->performance,$datum->total,4,true);
|
||||||
|
//转化率 = 完单数 / 总接单数
|
||||||
|
$datum->trans_rate = $this->_calc($datum->finish_num,$datum->get_count,4,true);
|
||||||
|
//变现值 = 总业绩 / 总接单数
|
||||||
|
$datum->cash_value = $this->_calc($datum->performance,$datum->get_count,2);
|
||||||
|
//拒单率 = 拒绝数 / 派单数
|
||||||
|
$datum->refuse_rate = $this->_calc($datum->refuse_count,$datum->dispatch_count,4,true);
|
||||||
|
//上门率 = 打卡数 / 接单数
|
||||||
|
$datum->arrive_rate = $this->_calc($datum->arrive_count,$datum->get_count,4,true);
|
||||||
|
//好评率
|
||||||
|
$datum->arrive_rate = $this->_calc($datum->good_count,$datum->finish_num,4,true);
|
||||||
|
|
||||||
|
$datum->avg_time_diff = $this->_calc($datum->avg_time_diff,3600*24,2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'echarts', 'echarts-t
|
||||||
title:"售后列表",
|
title:"售后列表",
|
||||||
icon: 'fa fa-list',
|
icon: 'fa fa-list',
|
||||||
url: function(row){
|
url: function(row){
|
||||||
return 'aftersales/aftersale/index?from=2&dispatch_admin_id='+row.id;
|
return 'aftersales/aftersale/index?from=2&man_id='+row.id;
|
||||||
},
|
},
|
||||||
extend: 'data-toggle="tooltip" data-container="body"',
|
extend: 'data-toggle="tooltip" data-container="body"',
|
||||||
classname: 'btn btn-xs btn-default btn-dialog',
|
classname: 'btn btn-xs btn-default btn-dialog',
|
||||||
|
|
|
||||||
|
|
@ -29,28 +29,31 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'echarts', 'echarts-t
|
||||||
columns: [
|
columns: [
|
||||||
[
|
[
|
||||||
//{field: 'id', title: __('Id')},
|
//{field: 'id', title: __('Id')},
|
||||||
{field: 'id', title: __('ID'),visible:true,operate: false},
|
{field: 'id', title: __('ID'),visible:true},
|
||||||
{field: 'admin_user', title: __('派单员'),operate: "LIKE"},
|
{field: 'name', title: __('姓名'),operate: "="},
|
||||||
{field: 'count_num', title: __('总订单数'),operate: false},
|
{field: 'tel', title: __('电话'),operate: "="},
|
||||||
{field: 'finish_num', title: __('完单数'),operate: false},
|
{field: 'area.name', title: __('城市'),operate: false},
|
||||||
{field: 'total', title: __('成效额(¥)'), operate: false},
|
{field: 'star', title: __('评分'),operate: false},
|
||||||
{field: 'performance', title: __('总业绩(¥)'), operate: false},
|
{field: 'performance', title: __('总业绩(¥)'), operate: false},
|
||||||
{field: 'cost_total', title: __('总成本(¥)'), operate: false},
|
{field: 'get_count', title: __('接单数'),operate: false},
|
||||||
{field: 'refund_total', title: __('退款金额(¥)'), operate: false},
|
{field: 'finish_num', title: __('完单数'),operate: false},
|
||||||
{field: 'refund_count', title: __('退款单数'), operate: false},
|
{field: 'cost', title: __('收入(¥)'), operate: false},
|
||||||
|
|
||||||
{field: 'performance_rate', title: __('利润率(%)'), operate: false},
|
{field: 'performance_rate', title: __('利润率(%)'), operate: false},
|
||||||
{field: 'trans_rate', title: __('转化率(%)'), operate: false},
|
{field: 'trans_rate', title: __('转化率(%)'), operate: false},
|
||||||
{field: 'cash_value', title: __('变现值'), operate: false},
|
{field: 'cash_value', title: __('变现值'), operate: false},
|
||||||
{field: 'performance_avg', title: __('客单利润(¥)'), operate: false},
|
{field: 'refuse_rate', title: __('拒单率(%)'), operate: false},
|
||||||
{field: 'total_avg', title: __('客单价(¥)'), operate: false},
|
{field: 'arrive_rate', title: __('上门率(%)'), operate: false},
|
||||||
|
{field: 'good_rate', title: __('好评率(%)'), operate: false},
|
||||||
|
|
||||||
{field: 'avg_time_diff', title: __('派单时效(天)'), operate: false},
|
{field: 'refund_total', title: __('退款金额(¥)'), operate: false},
|
||||||
|
{field: 'refund_count', title: __('退款单数'), operate: false},
|
||||||
|
|
||||||
|
|
||||||
|
{field: 'avg_time_diff', title: __('联系时效(天)'), operate: false},
|
||||||
|
|
||||||
//{field: 'admin_user', title: __('派单员'),operate: "LIKE",visible:false},
|
//{field: 'admin_user', title: __('派单员'),operate: "LIKE",visible:false},
|
||||||
//{field: 'city_name', title: __('城市'),operate: "LIKE",visible:false},
|
//{field: 'city_name', title: __('城市'),operate: "LIKE",visible:false},
|
||||||
//{field: 'city_name', title: __('城市'),operate: "LIKE",visible:false},
|
//{field: 'city_name', title: __('城市'),operate: "LIKE",visible:false},
|
||||||
{field: 'time_by', title: __('时间维度'), visible:false,searchList: {"1":__('录单时间'),"2":__('派单时间')},defaultValue:1, formatter: Table.api.formatter.normal},
|
|
||||||
{field: 'daterange', title: __('时间筛选'), addclass:'datetimerange',
|
{field: 'daterange', title: __('时间筛选'), addclass:'datetimerange',
|
||||||
autocomplete:false,
|
autocomplete:false,
|
||||||
operate: "RANGE",
|
operate: "RANGE",
|
||||||
|
|
@ -68,7 +71,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'echarts', 'echarts-t
|
||||||
title:"售后列表",
|
title:"售后列表",
|
||||||
icon: 'fa fa-list',
|
icon: 'fa fa-list',
|
||||||
url: function(row){
|
url: function(row){
|
||||||
return 'aftersales/aftersale/index?from=2&dispatch_admin_id='+row.id;
|
return 'aftersales/aftersale/index?from=3&man_id='+row.id;
|
||||||
},
|
},
|
||||||
extend: 'data-toggle="tooltip" data-container="body"',
|
extend: 'data-toggle="tooltip" data-container="body"',
|
||||||
classname: 'btn btn-xs btn-default btn-dialog',
|
classname: 'btn btn-xs btn-default btn-dialog',
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user