allocatr/application/admin/controller/statistics/Aftersale.php
2025-06-22 18:41:46 +08:00

364 lines
9.9 KiB
PHP

<?php
namespace app\admin\controller\statistics;
use app\admin\model\Admin;
use app\admin\model\Order;
use app\common\controller\Backend;
use think\Db;
use think\Model;
use function Symfony\Component\Clock\now;
/**
* 服务项目统计
*
* @icon fa fa-circle-o
*/
class Aftersale extends Backend
{
protected $noNeedRight = ['*'];
protected $relationSearch = true,$items,$itemsformattedTree,$sources;
public function _initialize()
{
$items = Db::name('item')
->where('status', 1)
->field(['id', 'title', 'key_word', 'pid'])
->order('pid', 'asc')
->order('sort', 'desc')
->select();
$start = now()->modify('-30 days')->format('Y-m-d');
$end_at = now()->format('Y-m-d');
$default_daterange = $start . ' - ' . $end_at;
$tree = $this->buildTree($items);
$formattedTree = $this->formatTree($tree);
$this->items = $items;
$this->itemsformattedTree = $formattedTree;
$this->view->assign("items", $formattedTree);
$this->view->assign("default_daterange", $default_daterange);
$sources = Db::name('source')
->where('status', 1)
->field(['id', 'title', 'key_word', 'pid'])
->order('pid', 'asc')
->order('sort', 'desc')
->select();
$this->sources = $sources;
$filtered = array_filter($sources, function ($item) {
return $item['pid'] == 0;
});
$pid_map = array_column($filtered, null, 'id');
$res = [];
foreach ($sources as $item) {
if ($item['pid'] != 0 && isset($pid_map[$item['pid']])) {
$res [] = [
...$item, 'ptitle' => $pid_map[$item['pid']]['title'],'name'=>$item['title'].' - '.$pid_map[$item['pid']]['title'],
];
}
}
$this->view->assign("sources", $res);
parent::_initialize();
}
public function index()
{
return $this->fetch('index');
}
public function dispatch()
{
$build = new Admin();
$build->alias('a')
->join('order b', 'a.id = b.admin_id', 'right')
->join('aftersale c', 'a.id = c.refund_admin_id', 'left')
->where('b.status', Order::STATUS_FINISHED);
$start = now()->modify('-30 days')->format('Y-m-d');
$end_at = now()->format('Y-m-d 23:29:59');
$filter = request()->get('range', '');
if (!empty($filter)) {
$arr = explode(' - ', $filter);
if (trim($arr[0])) {
$start = trim($arr[0]);
}
if (trim($arr[1])) {
$end_at = trim($arr[1]) . ' 23:29:59';
}
}
$keyword = request()->get('keyword');
$build->where('audit_time', '>=', $start);
$build->where('audit_time', '<=', $end_at);
if (!is_null($keyword)) {
$build->where(function ($q) use ($keyword) {
$q->where('nickname', 'like', '%' . $keyword . '%')
->whereor('mobile', 'like', '%' . $keyword . '%');
});
}
$build->group('a.id');
$build->field(
[
'a.id',
'a.nickname',
'a.mobile',
'count(b.id) order_total',
'count(c.id) after_total',
'sum(c.refund_amount) refund_amount',
]
);
$res = $build->paginate();
$total = $res->total();
$ress = $res->items();
// dd(Admin::getLastSql());
$data = [];
foreach ($ress as $res) {
$item = $res->toArray();
$item['rate'] = $this->mydiv($item['after_total'],$item['order_total']) . '%';
$data [] = $item;
}
return [
'rows' => $data,
'total' => $total
];
}
public function city()
{
$build = new Order();
$build->alias('a')
->join('aftersale c', 'a.id = c.order_id', 'left')
->where('a.status', Order::STATUS_FINISHED);
$start = now()->modify('-30 days')->format('Y-m-d');
$end_at = now()->format('Y-m-d 23:29:59');
$area_code = request()->get('area_id');
$source = request()->get('source');
$filter = request()->get('range', '');
if (!empty($filter)) {
$arr = explode(' - ', $filter);
if (trim($arr[0])) {
$start = trim($arr[0]);
}
if (trim($arr[1])) {
$end_at = trim($arr[1]) . ' 23:29:59';
}
}
$build->where('audit_time', '>=', $start);
$build->where('audit_time', '<=', $end_at);
$build->group('a.source,a.area_id');
if ($area_code) {
$build->where('area_id', 'like', $this->getSelectAreaCode($area_code) . '%');
}
if ($source) {
$build->where('source', $source);
}
$build->field(
[
'a.source',
'a.area_id',
'count(a.id) order_total',
'count(c.id) after_total',
'sum(c.refund_amount) refund_amount',
]
)->with([
'area' => function ($q) {
$q->field('id,area_code,merge_name');
},
'source' => function ($q) {
$q->field('id,title');
},
]);
$res = $build->paginate();
$total = $res->total();
$ress = $res->items();
// dd(Admin::getLastSql());
$data = [];
foreach ($ress as $res) {
$item = $res->toArray();
$item['rate'] = $this->mydiv($item['after_total'],$item['order_total']) . '%';
$data [] = $item;
}
return [
'rows' => $data,
'total' => $total
];
}
public function item()
{
$build = new Order();
$build->alias('a')
->join('aftersale c', 'a.id = c.order_id', 'left')
->where('a.status', Order::STATUS_FINISHED);
$start = now()->modify('-30 days')->format('Y-m-d');
$end_at = now()->format('Y-m-d 23:29:59');
$item_id = request()->get('item_id');
$source = request()->get('source');
$filter = request()->get('range', '');
if (!empty($filter)) {
$arr = explode(' - ', $filter);
if (trim($arr[0])) {
$start = trim($arr[0]);
}
if (trim($arr[1])) {
$end_at = trim($arr[1]) . ' 23:29:59';
}
}
$build->where('audit_time', '>=', $start);
$build->where('audit_time', '<=', $end_at);
$build->group('a.source,a.item_id,a.item_title');
if ($item_id) {
$item_ids = $this->getItemsById($item_id);
$item_ids [] = $item_id;
$build->whereIn('item_id', $item_ids);
}
if ($source) {
$build->where('source', $source);
}
$build->field(
[
'a.source',
'a.item_id',
'a.item_title',
'count(a.id) order_total',
'count(c.id) after_total',
'sum(c.refund_amount) refund_amount',
]
)->with([
'source' => function ($q) {
$q->field('id,title');
},
]);
$res = $build->paginate();
$total = $res->total();
$ress = $res->items();
// dd(Admin::getLastSql());
$data = [];
foreach ($ress as $res) {
$item = $res->toArray();
$item['rate'] = $this->mydiv($item['after_total'],$item['order_total']) . '%';
$data [] = $item;
}
return [
'rows' => $data,
'total' => $total
];
}
private function mydiv($a, $b, int $scale = 4, $is_percent = true): int|string
{
$val = $b > 0 ? bcdiv($a, $b, $scale) : 0;
if ($is_percent) {
return bcmul($val, 100, 2);
}
return $val;
}
public function worker()
{
$build = new \app\admin\model\Worker();
$build->alias('a')
->join('order b', 'a.id = b.worker_id', 'right')
->join('aftersale c', 'a.id = c.worker_id', 'left')
->where('b.status', Order::STATUS_FINISHED);
$start = now()->modify('-30 days')->format('Y-m-d');
$end_at = now()->format('Y-m-d 23:29:59');
$filter = request()->get('range', '');
if (!empty($filter)) {
$arr = explode(' - ', $filter);
if (trim($arr[0])) {
$start = trim($arr[0]);
}
if (trim($arr[1])) {
$end_at = trim($arr[1]) . ' 23:29:59';
}
}
$keyword = request()->get('keyword');
$build->where('audit_time', '>=', $start);
$build->where('audit_time', '<=', $end_at);
if (!is_null($keyword)) {
$build->where(function ($q) use ($keyword) {
$q->where('name', 'like', '%' . $keyword . '%')
->whereor('a.tel', 'like', '%' . $keyword . '%');
});
}
$build->group('a.id');
$build->field(
[
'a.id',
'a.name',
'a.tel',
'count(b.id) order_total',
'count(c.id) after_total',
'sum(c.refund_amount) refund_amount',
]
);
$res = $build->paginate();
$total = $res->total();
$ress = $res->items();
// dd(Admin::getLastSql());
$data = [];
foreach ($ress as $res) {
$item = $res->toArray();
$item['rate'] = $this->mydiv($item['after_total'],$item['order_total']) . '%';
$data [] = $item;
}
return [
'rows' => $data,
'total' => $total
];
}
}