610 lines
23 KiB
PHP
610 lines
23 KiB
PHP
<?php
|
||
|
||
namespace app\admin\controller\statistics;
|
||
|
||
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\admin\model\WorkerItem;
|
||
use app\common\controller\Backend;
|
||
use PDOStatement;
|
||
use think\Collection;
|
||
use think\Exception;
|
||
use think\exception\DbException;
|
||
use think\Loader;
|
||
use think\response\Json;
|
||
use function Symfony\Component\Clock\now;
|
||
|
||
/**
|
||
* 师傅列管理
|
||
*
|
||
* @icon fa fa-circle-o
|
||
*/
|
||
class Worker extends Backend
|
||
{
|
||
|
||
/**
|
||
* Sworker模型对象
|
||
* @var \app\admin\model\Worker
|
||
*/
|
||
protected $model = null;
|
||
/**
|
||
* @var Order
|
||
*/
|
||
private Order $OrderModel;
|
||
/**
|
||
* @var OrderDispatch
|
||
*/
|
||
private OrderDispatch $DispatchModel;
|
||
|
||
|
||
protected $relationSearch = true;
|
||
|
||
public function _initialize()
|
||
{
|
||
parent::_initialize();
|
||
$this->model = new \app\admin\model\Worker();
|
||
$this->OrderModel = new Order();
|
||
$this->DispatchModel = new OrderDispatch();
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
|
||
* 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
|
||
* 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
|
||
*/
|
||
|
||
/**
|
||
* 查看
|
||
*
|
||
* @return string|Json
|
||
* @throws Exception
|
||
* @throws DbException
|
||
*/
|
||
public function index()
|
||
{
|
||
|
||
$today = now()->format('Y-m-01');
|
||
$today_end = now()->format('Y-m-d');
|
||
//设置过滤方法
|
||
$this->request->filter(['strip_tags', 'trim']);
|
||
if (false === $this->request->isAjax()) {
|
||
$appkey = config('map.baidu_app_key');
|
||
$this->assign('mapkey',$appkey);
|
||
|
||
$count = \app\admin\model\Worker::count();
|
||
$active_count = \app\admin\model\Worker::where('location_update_time', '>=', date('Y-m-d H:i:s', strtotime('-30 days')))
|
||
->count();
|
||
|
||
$add_count_1 = \app\admin\model\Worker::where('create_time', '>=', date('Y-m-d'))
|
||
->count();
|
||
|
||
$active_count_7 = \app\admin\model\Worker::where('create_time', '>=', date('Y-m-d H:i:s', strtotime('-7 days')))
|
||
->count();
|
||
|
||
$this->assign('count',$count);
|
||
$this->assign('active_count',$active_count);
|
||
$this->assign('add_count_1',$add_count_1);
|
||
$this->assign('add_count_7',$active_count_7);
|
||
|
||
//待接单
|
||
//$todo_count = OrderDispatch::where('status',OrderDispatch::STATUS_TOGET)->count();
|
||
//进行中
|
||
//$ing_count = OrderDispatch::whereIn('status',[OrderDispatch::STATUS_GOTIT,OrderDispatch::STATUS_PLANIT,OrderDispatch::STATUS_CLOCK])->count();
|
||
//待验收
|
||
//$check_count = OrderDispatch::where('status',Order::STATUS_CHECKING)->count();
|
||
//售后待处理
|
||
//$aftersale_count = Aftersale::where('status',1)->count();
|
||
|
||
/* $this->assign('todo_count',$todo_count);
|
||
$this->assign('ing_count',$ing_count);
|
||
$this->assign('check_count',$check_count);
|
||
$this->assign('aftersale_count',$aftersale_count);*/
|
||
|
||
//师傅坐标
|
||
$list = \app\admin\model\Worker::where('lng','>',0)->field(['lng','lat'])->select();
|
||
$arr = [];
|
||
foreach ($list as $item){
|
||
$arr[] = [
|
||
$item->lng, $item->lat,
|
||
];
|
||
}
|
||
$this->assign('locationData',json_encode($arr));
|
||
|
||
$this->assignconfig('default_daterange',now()->format('Y-m-01 00:00:00').' - '.now()->format('Y-m-d 23:59:59'));
|
||
return $this->view->fetch();
|
||
}
|
||
//如果发送的来源是 Selectpage,则转发到 Selectpage
|
||
if ($this->request->request('keyField')) {
|
||
return $this->selectpage();
|
||
}
|
||
|
||
$filter = $this->request->param('filter');
|
||
$filter = json_decode($filter,true);
|
||
if(!empty($filter['daterange'])){
|
||
$arr = explode(' - ',$filter['daterange']);
|
||
if(trim($arr[0])){
|
||
$filter['start_time'] = trim($arr[0]);
|
||
}
|
||
if(trim($arr[1])){
|
||
$filter['end_time'] = trim($arr[1]);
|
||
}
|
||
}
|
||
|
||
if(!empty($filter['item_id']))
|
||
{
|
||
$item_id = $filter['item_id'];
|
||
$filter['worker_ids'] = WorkerItem::where('item_id',$item_id)->column('worker_id');
|
||
}
|
||
|
||
//派单表
|
||
$dispatchSubsql = $this->dispatchSubsql($filter);
|
||
//订单表
|
||
$orderSubsql = $this->oderSubsql($filter);
|
||
//评分表
|
||
$viewSubsql = $this->viewSubsql($filter);
|
||
|
||
|
||
[$where, $sort, $order, $offset, $limit] = $this->buildparams();
|
||
$list = $this->model->alias('fa_worker')
|
||
->with(['area2','items'])
|
||
->field([
|
||
'fa_worker.*',
|
||
'IFNULL(a.dispatch_count, 0) AS dispatch_count',
|
||
'IFNULL(a.get_js_count, 0) AS get_js_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);
|
||
|
||
$data = [];
|
||
$worker_ids = [];
|
||
foreach ($list->items() as $item){
|
||
$dt = $item->toArray();
|
||
$tel = $dt['tel'];
|
||
if (preg_match('/^\d{7,}$/', $tel)) {
|
||
$dt['tel'] = mb_substr($tel, 0, 3, 'UTF-8') . '****' . mb_substr($tel, -4, null, 'UTF-8');
|
||
} else {
|
||
// 不处理非手机号,比如中文名称
|
||
$dt['tel'] = $tel;
|
||
}
|
||
$data[] = $dt;
|
||
$worker_ids [] = $item['id'];
|
||
}
|
||
|
||
$worker_item = WorkerItem::whereIn('worker_id',$worker_ids)->where('item_path_id',1)
|
||
->field('worker_id,item_id')->select();
|
||
|
||
$allItemList = \app\admin\model\Item::where('level',1)->select();
|
||
|
||
$allItems= [];
|
||
foreach ($allItemList as $item){
|
||
$allItems[$item->id] = $item->title;
|
||
}
|
||
|
||
|
||
$worker_item_map = [];
|
||
// dd($worker_item);
|
||
foreach ($worker_item as $item){
|
||
$worker_item_map[$item->worker_id] [] = $item->item_id;
|
||
}
|
||
|
||
foreach ($list as &$datum){
|
||
$worker_item = [];
|
||
// dd($worker_item_map);
|
||
if (key_exists($datum['id'],$worker_item_map)){
|
||
foreach ($worker_item_map[$datum['id']] as $item){
|
||
$worker_item[] = $allItems[$item]??'';
|
||
}
|
||
}
|
||
$datum['worker_item'] = implode(',',$worker_item);
|
||
}
|
||
|
||
|
||
$this->_toList($list);
|
||
$result = ['total' => $list->total(), 'rows' => $list->items()];
|
||
return json($result);
|
||
}
|
||
|
||
|
||
/**
|
||
* @return bool|Collection|PDOStatement|string
|
||
* @throws DbException
|
||
*/
|
||
public function viewSubsql($filter=[]){
|
||
//评分表
|
||
$viewSubsql = OrderReview::where('worker_star',5)->field(['worker_id','count(*) as good_count']);
|
||
|
||
if(!empty($filter['start_time'])){
|
||
$viewSubsql->where('create_time','>=',$filter['start_time']);
|
||
}
|
||
if(!empty($filter['end_time'])){
|
||
$viewSubsql->where('create_time','<=',$filter['end_time']);
|
||
}
|
||
|
||
if(!empty($filter['worker_ids'])){
|
||
$viewSubsql->where('worker_id','in',$filter['worker_ids']);
|
||
}
|
||
|
||
return $viewSubsql->group('worker_id')->buildSql();
|
||
}
|
||
|
||
/**
|
||
* @return bool|PDOStatement|string|Collection
|
||
* @throws DbException
|
||
*/
|
||
public function dispatchSubsql($filter): Collection|bool|string|PDOStatement
|
||
{
|
||
$builder = new OrderDispatch();
|
||
$fields = [
|
||
'worker_id',
|
||
// 使用 IFNULL 确保结果为 null 时返回 0
|
||
"IFNULL(COUNT(*), 0) AS dispatch_count", //分配数
|
||
"IFNULL(COUNT(CASE WHEN status NOT IN (0, -10) THEN 1 END), 0) AS get_count", //接单数
|
||
|
||
"IFNULL(COUNT(CASE WHEN status IN (30, 60) THEN 1 END), 0) AS get_js_count", //接单数
|
||
//"COUNT(CASE WHEN status IN (60) THEN 1 END) AS finish_count", //完成数
|
||
"IFNULL(COUNT(CASE WHEN status IN (-10) THEN 1 END), 0) AS refuse_count", //拒绝数
|
||
"IFNULL(COUNT(arrive_time), 0) AS arrive_count", //上门数
|
||
"IFNULL(AVG(CASE WHEN status = 60 AND arrive_time IS NOT NULL THEN UNIX_TIMESTAMP(arrive_time) - UNIX_TIMESTAMP(create_time) END), 0) AS avg_time_diff", //联系时效
|
||
];
|
||
$builder->field($fields);
|
||
|
||
if(!empty($filter['start_time'])){
|
||
$builder->where('create_time','>=',$filter['start_time']);
|
||
}
|
||
if(!empty($filter['end_time'])){
|
||
$builder->where('create_time','<=',$filter['end_time']);
|
||
}
|
||
|
||
if(!empty($filter['worker_ids'])){
|
||
$builder->where('worker_id','in',$filter['worker_ids']);
|
||
}
|
||
|
||
|
||
$builder->group('worker_id');
|
||
return $builder->buildSql();
|
||
}
|
||
|
||
|
||
|
||
//图表统计
|
||
|
||
/**
|
||
* @throws DbException
|
||
*/
|
||
public function oderSubsql($filter = []): Collection|bool|string|PDOStatement
|
||
{
|
||
|
||
$orderValid = implode(',',(new Order())->tabStatus(Order::TAB_VALID));
|
||
|
||
//"COUNT(CASE WHEN status IN (".$orderValid.") THEN 1 END) AS ing_num",
|
||
$fields = [
|
||
'worker_id',
|
||
// 使用 IFNULL 确保结果为 null 时返回 0
|
||
"IFNULL(COUNT(CASE WHEN status = 60 THEN 1 END), 0) AS finish_num", //完成数
|
||
//"COUNT(CASE WHEN status IN (".$orderValid.") THEN 1 END) AS count_num", //总订单数 (排除取消 和草稿)
|
||
"IFNULL(SUM(CASE WHEN status = 60 THEN total END), 0) AS total", //成效额
|
||
"IFNULL(SUM(CASE WHEN status = 60 THEN performance END), 0) AS performance", //业绩
|
||
"IFNULL(SUM(CASE WHEN status = 60 THEN cost END), 0) AS cost", //成效额
|
||
|
||
// "SUM(CASE WHEN status = 60 THEN (cost + material_cost) END) AS cost_total", //总成本
|
||
|
||
"IFNULL(SUM(CASE WHEN status = 60 THEN (refund_amount + worker_refund_amount) END), 0) AS refund_total", //退款总数
|
||
"IFNULL(COUNT(CASE WHEN refund_amount > 0 OR worker_refund_amount > 0 THEN 1 END), 0) AS refund_count", //退款订单数量
|
||
//"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 = (new Order())->field($fields);
|
||
|
||
if(!empty($filter['start_time'])){
|
||
$builder->where('create_time','>=',$filter['start_time']);
|
||
}
|
||
if(!empty($filter['end_time'])){
|
||
$builder->where('create_time','<=',$filter['end_time']);
|
||
}
|
||
if(!empty($filter['worker_ids'])){
|
||
$builder->where('worker_id','in',$filter['worker_ids']);
|
||
}
|
||
|
||
//->where('dispatch_admin_id','>',0);
|
||
return $builder->group('worker_id')->buildSql();
|
||
|
||
}
|
||
|
||
|
||
/**
|
||
* @param $a
|
||
* @param $b
|
||
* @param int $scale
|
||
* @param bool $is_percent
|
||
* @return int|string
|
||
*/
|
||
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->good_rate = $this->_calc($datum->good_count,$datum->finish_num,4,true);
|
||
//及时联系率=(已预约上门数/已接单数)。
|
||
$datum->get_time_rate = $this->_calc($datum->get_js_count,$datum->get_count,4,true);
|
||
|
||
|
||
$datum->avg_time_diff = $this->_calc($datum->avg_time_diff,3600,2);
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* 生成查询所需要的条件,排序方式
|
||
* @param mixed $searchfields 快速查询的字段
|
||
* @param boolean $relationSearch 是否关联查询
|
||
* @return array
|
||
*/
|
||
protected function buildparams($searchfields = null, $relationSearch = null)
|
||
{
|
||
$searchfields = is_null($searchfields) ? $this->searchFields : $searchfields;
|
||
$relationSearch = is_null($relationSearch) ? $this->relationSearch : $relationSearch;
|
||
$search = $this->request->get("search", '');
|
||
$filter = $this->request->get("filter", '');
|
||
$op = $this->request->get("op", '', 'trim');
|
||
$sort = $this->request->get("sort", !empty($this->model) && $this->model->getPk() ? $this->model->getPk() : 'id');
|
||
|
||
$asortFields = ['dispatch_count','get_count','refuse_count','arrive_count'];
|
||
$bsortFields = ['finish_num','total','performance','refund_total','refund_count','cost'];
|
||
$csortFields = ['good_count'];
|
||
|
||
if(!empty($sort) ){
|
||
if(in_array($sort,$asortFields)){
|
||
$sort = 'a.'.$sort;
|
||
}
|
||
if(in_array($sort,$bsortFields)){
|
||
$sort = 'b.'.$sort;
|
||
}
|
||
if(in_array($sort,$csortFields)){
|
||
$sort = 'c.'.$sort;
|
||
}
|
||
}
|
||
|
||
$order = $this->request->get("order", "DESC");
|
||
$offset = max(0, $this->request->get("offset/d", 0));
|
||
$limit = max(0, $this->request->get("limit/d", 0));
|
||
$limit = $limit ?: 999999;
|
||
//新增自动计算页码
|
||
$page = $limit ? intval($offset / $limit) + 1 : 1;
|
||
if ($this->request->has("page")) {
|
||
$page = max(0, $this->request->get("page/d", 1));
|
||
}
|
||
$this->request->get([config('paginate.var_page') => $page]);
|
||
$filter = (array)json_decode($filter, true);
|
||
unset($filter['daterange']);
|
||
|
||
|
||
|
||
$area_id = $filter['area_id']??null;
|
||
// dd($area_id);
|
||
unset($filter['area_id']);
|
||
if(!empty($area_id)){
|
||
$filter['fa_worker.area_id'] = $this->getSelectAreaCode($area_id);
|
||
}
|
||
|
||
if(!empty($filter['item_id']))
|
||
{
|
||
$item_id = $filter['item_id'];
|
||
$filter['fa_worker.id'] = WorkerItem::where('item_id',$item_id)->column('worker_id');
|
||
unset($filter['item_id']);
|
||
}
|
||
|
||
$op = (array)json_decode($op, true);
|
||
$op['fa_worker.area_id'] = 'LIKE%';
|
||
$op['fa_worker.id'] = 'IN';
|
||
|
||
$filter = $filter ? $filter : [];
|
||
$where = [];
|
||
$alias = [];
|
||
$bind = [];
|
||
$name = '';
|
||
$aliasName = '';
|
||
if (!empty($this->model) && $relationSearch) {
|
||
$name = $this->model->getTable();
|
||
$alias[$name] = Loader::parseName(basename(str_replace('\\', '/', get_class($this->model))));
|
||
$aliasName = $alias[$name] . '.';
|
||
}
|
||
$sortArr = explode(',', $sort);
|
||
foreach ($sortArr as $index => & $item) {
|
||
$item = stripos($item, ".") === false ? $aliasName . trim($item) : $item;
|
||
}
|
||
unset($item);
|
||
$sort = implode(',', $sortArr);
|
||
$adminIds = $this->getDataLimitAdminIds();
|
||
if (is_array($adminIds)) {
|
||
$where[] = [$aliasName . $this->dataLimitField, 'in', $adminIds];
|
||
}
|
||
if ($search) {
|
||
$searcharr = is_array($searchfields) ? $searchfields : explode(',', $searchfields);
|
||
foreach ($searcharr as $k => &$v) {
|
||
$v = stripos($v, ".") === false ? $aliasName . $v : $v;
|
||
}
|
||
unset($v);
|
||
$where[] = [implode("|", $searcharr), "LIKE", "%{$search}%"];
|
||
}
|
||
$index = 0;
|
||
foreach ($filter as $k => $v) {
|
||
if (!preg_match('/^[a-zA-Z0-9_\-\.]+$/', $k)) {
|
||
continue;
|
||
}
|
||
$sym = $op[$k] ?? '=';
|
||
if (stripos($k, ".") === false) {
|
||
$k = $aliasName . $k;
|
||
}
|
||
$v = !is_array($v) ? trim($v) : $v;
|
||
$sym = strtoupper($op[$k] ?? $sym);
|
||
//null和空字符串特殊处理
|
||
if (!is_array($v)) {
|
||
if (in_array(strtoupper($v), ['NULL', 'NOT NULL'])) {
|
||
$sym = strtoupper($v);
|
||
}
|
||
if (in_array($v, ['""', "''"])) {
|
||
$v = '';
|
||
$sym = '=';
|
||
}
|
||
}
|
||
|
||
switch ($sym) {
|
||
case '=':
|
||
case '<>':
|
||
$where[] = [$k, $sym, (string)$v];
|
||
break;
|
||
case 'LIKE':
|
||
case 'NOT LIKE':
|
||
case 'LIKE %...%':
|
||
case 'NOT LIKE %...%':
|
||
$where[] = [$k, trim(str_replace('%...%', '', $sym)), "%{$v}%"];
|
||
break;
|
||
// ✅ 新增:右匹配(like%)
|
||
case 'LIKE%':
|
||
$where[] = [$k, 'LIKE', "{$v}%"];
|
||
break;
|
||
|
||
// ✅ 新增:左匹配(%like)
|
||
case '%LIKE':
|
||
$where[] = [$k, 'LIKE', "%{$v}"];
|
||
break;
|
||
case '>':
|
||
case '>=':
|
||
case '<':
|
||
case '<=':
|
||
$where[] = [$k, $sym, intval($v)];
|
||
break;
|
||
case 'FINDIN':
|
||
case 'FINDINSET':
|
||
case 'FIND_IN_SET':
|
||
$v = is_array($v) ? $v : explode(',', str_replace(' ', ',', $v));
|
||
$findArr = array_values($v);
|
||
foreach ($findArr as $idx => $item) {
|
||
$bindName = "item_" . $index . "_" . $idx;
|
||
$bind[$bindName] = $item;
|
||
$where[] = "FIND_IN_SET(:{$bindName}, `" . str_replace('.', '`.`', $k) . "`)";
|
||
}
|
||
break;
|
||
case 'IN':
|
||
case 'IN(...)':
|
||
case 'NOT IN':
|
||
case 'NOT IN(...)':
|
||
$where[] = [$k, str_replace('(...)', '', $sym), is_array($v) ? $v : explode(',', $v)];
|
||
break;
|
||
case 'BETWEEN':
|
||
case 'NOT BETWEEN':
|
||
$arr = array_slice(explode(',', $v), 0, 2);
|
||
if (stripos($v, ',') === false || !array_filter($arr, function ($v) {
|
||
return $v != '' && $v !== false && $v !== null;
|
||
})) {
|
||
continue 2;
|
||
}
|
||
//当出现一边为空时改变操作符
|
||
if ($arr[0] === '') {
|
||
$sym = $sym == 'BETWEEN' ? '<=' : '>';
|
||
$arr = $arr[1];
|
||
} elseif ($arr[1] === '') {
|
||
$sym = $sym == 'BETWEEN' ? '>=' : '<';
|
||
$arr = $arr[0];
|
||
}
|
||
$where[] = [$k, $sym, $arr];
|
||
break;
|
||
case 'RANGE':
|
||
case 'NOT RANGE':
|
||
$v = str_replace(' - ', ',', $v);
|
||
$arr = array_slice(explode(',', $v), 0, 2);
|
||
if (stripos($v, ',') === false || !array_filter($arr)) {
|
||
continue 2;
|
||
}
|
||
//当出现一边为空时改变操作符
|
||
if ($arr[0] === '') {
|
||
$sym = $sym == 'RANGE' ? '<=' : '>';
|
||
$arr = $arr[1];
|
||
} elseif ($arr[1] === '') {
|
||
$sym = $sym == 'RANGE' ? '>=' : '<';
|
||
$arr = $arr[0];
|
||
}
|
||
$tableArr = explode('.', $k);
|
||
if (count($tableArr) > 1 && $tableArr[0] != $name && !in_array($tableArr[0], $alias)
|
||
&& !empty($this->model) && $this->relationSearch) {
|
||
//修复关联模型下时间无法搜索的BUG
|
||
$relation = Loader::parseName($tableArr[0], 1, false);
|
||
$alias[$this->model->$relation()->getTable()] = $tableArr[0];
|
||
}
|
||
$where[] = [$k, str_replace('RANGE', 'BETWEEN', $sym) . ' TIME', $arr];
|
||
break;
|
||
case 'NULL':
|
||
case 'IS NULL':
|
||
case 'NOT NULL':
|
||
case 'IS NOT NULL':
|
||
$where[] = [$k, strtolower(str_replace('IS ', '', $sym))];
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
$index++;
|
||
}
|
||
if (!empty($this->model)) {
|
||
$this->model->alias($alias);
|
||
}
|
||
$model = $this->model;
|
||
$where = function ($query) use ($where, $alias, $bind, &$model) {
|
||
if (!empty($model)) {
|
||
$model->alias($alias);
|
||
$model->bind($bind);
|
||
}
|
||
foreach ($where as $k => $v) {
|
||
if (is_array($v)) {
|
||
call_user_func_array([$query, 'where'], $v);
|
||
} else {
|
||
$query->where($v);
|
||
}
|
||
}
|
||
};
|
||
return [$where, $sort, $order, $offset, $limit, $page, $alias, $bind];
|
||
}
|
||
|
||
}
|