This commit is contained in:
xman 2025-04-28 15:42:48 +08:00
parent df63a6c89f
commit b0739941af
4 changed files with 121 additions and 94 deletions

View File

@ -58,7 +58,7 @@ class Aftersale extends Backend
if ($this->request->isAjax()) {
$from = $this->request->param('from',1);
$dispatch_admin_id = $this->request->param('dispatch_admin_id');
$man_id = $this->request->param('man_id');
//如果发送的来源是Selectpage则转发到Selectpage
if ($this->request->request('keyField')) {
@ -73,9 +73,16 @@ class Aftersale extends Backend
if($from == 2){
//$builder->where('refund_amount','>',0);
//$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)
->paginate($limit);

View File

@ -6,7 +6,10 @@ use app\admin\model\Admin;
use app\admin\model\Aftersale;
use app\admin\model\Order;
use app\admin\model\OrderDispatch;
use app\admin\model\OrderReview;
use app\common\controller\Backend;
use PDOStatement;
use think\Collection;
use think\Exception;
use think\exception\DbException;
use think\response\Json;
@ -108,126 +111,140 @@ class Worker extends Backend
if ($this->request->request('keyField')) {
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();
$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)
->order($sort, $order)
->paginate($limit);
$this->_toList($list);
$result = ['total' => $list->total(), 'rows' => $list->items()];
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){
$orderValid = implode(',',$this->model->tabStatus(Order::TAB_VALID));
/**
* @throws DbException
*/
public function oderSubsql()
{
$orderValid = implode(',',(new Order())->tabStatus(Order::TAB_VALID));
//"COUNT(CASE WHEN status IN (".$orderValid.") THEN 1 END) AS ing_num",
$fields = [
'dispatch_admin_id',
'worker_id',
"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 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", //退款总数
"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",
];
$builder = $this->model
->field($fields);
$builder = (new Order())->field($fields);
//->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 $b
* @param $scale
* @param int $scale
* @param bool $is_percent
* @return int|string
*/
private function _calc($a,$b,$scale=4,$is_percent=false){
$val = $b > 0 ? bcdiv($a,$b,$scale) : 0;
private function _calc($a, $b, int $scale=4, bool $is_percent=false): int|string
{
$a = $a??0;
$b = $b??0;
$val = $b > 0 ? bcdiv($a,$b,$scale) : '0.00';
if($is_percent){
return bcmul($val,100,2);
}
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);
}
}
}

View File

@ -68,7 +68,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'echarts', 'echarts-t
title:"售后列表",
icon: 'fa fa-list',
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"',
classname: 'btn btn-xs btn-default btn-dialog',

View File

@ -29,28 +29,31 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'echarts', 'echarts-t
columns: [
[
//{field: 'id', title: __('Id')},
{field: 'id', title: __('ID'),visible:true,operate: false},
{field: 'admin_user', title: __('派单员'),operate: "LIKE"},
{field: 'count_num', title: __('总订单数'),operate: false},
{field: 'finish_num', title: __('完单数'),operate: false},
{field: 'total', title: __('成效额(¥)'), operate: false},
{field: 'id', title: __('ID'),visible:true},
{field: 'name', title: __('姓名'),operate: "="},
{field: 'tel', title: __('电话'),operate: "="},
{field: 'area.name', title: __('城市'),operate: false},
{field: 'star', title: __('评分'),operate: false},
{field: 'performance', title: __('总业绩(¥)'), operate: false},
{field: 'cost_total', title: __('总成本(¥)'), operate: false},
{field: 'refund_total', title: __('退款金额(¥)'), operate: false},
{field: 'refund_count', title: __('退款单数'), operate: false},
{field: 'get_count', title: __('接单数'),operate: false},
{field: 'finish_num', title: __('完单数'),operate: false},
{field: 'cost', title: __('收入(¥)'), operate: false},
{field: 'performance_rate', title: __('利润率(%)'), operate: false},
{field: 'trans_rate', title: __('转化率(%)'), operate: false},
{field: 'cash_value', title: __('变现值'), operate: false},
{field: 'performance_avg', title: __('客单利润(¥)'), operate: false},
{field: 'total_avg', title: __('客单价(¥)'), operate: false},
{field: 'refuse_rate', 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: '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',
autocomplete:false,
operate: "RANGE",
@ -68,7 +71,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'echarts', 'echarts-t
title:"售后列表",
icon: 'fa fa-list',
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"',
classname: 'btn btn-xs btn-default btn-dialog',