diff --git a/addons/alioss/config.php b/addons/alioss/config.php index b872fd9..0b96622 100644 --- a/addons/alioss/config.php +++ b/addons/alioss/config.php @@ -108,7 +108,7 @@ return [ 'title' => '上传有效时长', 'type' => 'string', 'content' => [], - 'value' => '600', + 'value' => '3000', 'rule' => 'required', 'msg' => '', 'tip' => '用户停留页面上传有效时长,单位秒', @@ -120,7 +120,7 @@ return [ 'title' => '最大可上传', 'type' => 'string', 'content' => [], - 'value' => '10M', + 'value' => '20M', 'rule' => 'required', 'msg' => '', 'tip' => '', diff --git a/application/admin/controller/Item.php b/application/admin/controller/Item.php index 16c47e2..9099e9f 100644 --- a/application/admin/controller/Item.php +++ b/application/admin/controller/Item.php @@ -137,7 +137,7 @@ class Item extends Backend $params['level'] = $parent->value('level') + 1; } }else{ - $params['level'] = 0; + $params['level'] = 1; } diff --git a/application/admin/controller/Order.php b/application/admin/controller/Order.php index de93262..58830fc 100644 --- a/application/admin/controller/Order.php +++ b/application/admin/controller/Order.php @@ -202,9 +202,9 @@ class Order extends Backend } - if ($group == 2 ) { + if ($group == 2 ) { // 录单员 $build->where('admin_id',$user->id); - }elseif ($group == 6){ + }elseif ($group == 6){ // 派单员 // 生成 SQL 语句 $ids = $user->area_ids ?? ''; if ($ids == '') { diff --git a/application/admin/controller/workers/Worker.php b/application/admin/controller/workers/Worker.php index 62fccfc..693b903 100644 --- a/application/admin/controller/workers/Worker.php +++ b/application/admin/controller/workers/Worker.php @@ -13,6 +13,7 @@ use fast\Tree; use think\Db; use think\exception\PDOException; use think\exception\ValidateException; +use think\Loader; /** * 师傅列管理 @@ -27,7 +28,8 @@ class Worker extends Backend * Worker模型对象 * @var \app\admin\model\Worker */ - protected $model = null,$items; + protected $model = null; + protected $items; public function _initialize() { @@ -74,8 +76,18 @@ class Worker extends Backend { //当前是否为关联查询 $this->relationSearch = true; + $this->assignconfig('permissions', [ + 'export' => !empty(array_intersect($this->auth->getGroupIds(),[1,11])), + ]); + //设置过滤方法 $this->request->filter(['strip_tags', 'trim']); + $items = $this->items; + $filtered = array_filter($items, function ($item) { + return $item['pid'] == 0; + }); + + $pid_map = array_column($filtered, null, 'id'); if ($this->request->isAjax()) { //如果发送的来源是Selectpage,则转发到Selectpage if ($this->request->request('keyField')) { @@ -83,7 +95,10 @@ class Worker extends Backend } list($where, $sort, $order, $offset, $limit) = $this->buildparams(); $area_code = request()->get('area_id'); - $item_id = request()->get('item_id'); + $filter = (array)json_decode(input()['filter'] ?? '', true); + $area_id = $filter['area_id'] ?? false; + $item_id = $filter['item_id'] ?? false; + $keyword = request()->get('keyword'); $build = $this->model ->with(['area','admin' => function($q){ @@ -97,9 +112,16 @@ class Worker extends Backend $q->where('name', 'like', '%' . $keyword . '%')->whereOr('tel', 'like', '%' . $keyword . '%'); }); } + if ($area_id) { + $build->where('area_id', 'like', $this->getSelectAreaCode($area_id) . '%'); + } if ($item_id) { - $build->join('worker_item', 'worker_item.worker_id = worker.id', 'left'); - $build->where('worker_item.item_id', $item_id); + $item_ids = $this->getItemsById($item_id); + $item_ids [] = $item_id; + + $worker_ids = WorkerItem::whereIn('item_id',$item_ids)->column('worker_id'); + + $build->whereIn('id', $worker_ids); } if ($area_code) { @@ -108,32 +130,43 @@ class Worker extends Backend $list = $build ->paginate($limit); + $data = []; + $worker_ids = []; + foreach ($list->items() as $item){ + $dt = $item->toArray(); + $dt['tel'] = substr($dt['tel'], 0, 3) . '****' . substr($dt['tel'], -4); + $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(); + $worker_item_map = []; +// dd($worker_item); + foreach ($worker_item as $item){ + $worker_item_map[$item->worker_id] [] = $item->item_id; + } + foreach ($data as &$datum){ +// dd($worker_item_map); + if (key_exists($datum['id'],$worker_item_map)){ + foreach ($worker_item_map[$datum['id']] as $item){ + $datum ['worker_item'][] = trim($pid_map[$item]['title']); + } + }else{ + $datum ['worker_item'] = []; + } + $datum['worker_item'] = implode(',',$datum['worker_item']); + } - $result = array("total" => $list->total(), "rows" => $list->items()); + + $result = array("total" => $list->total(), "rows" => $data); return json($result); } - $items = Db::name('item') - ->where('status', 1) - ->field(['id', 'title', 'key_word', 'pid']) - ->order('pid', 'asc') - ->order('sort', 'desc') - ->select(); - $filtered = array_filter($items, function ($item) { - return $item['pid'] == 0; - }); - $pid_map = array_column($filtered, null, 'id'); - $res_items = []; - foreach ($items as $item) { - if ($item['pid'] != 0 && isset($pid_map[$item['pid']])) { - $res_items [] = [ - ...$item, 'ptitle' => $pid_map[$item['pid']]['title'] - ]; - } - } - $this->view->assign('items', $res_items); + $tree = $this->buildTree($items); + $formattedTree = $this->formatTree($tree); + $this->view->assign('items', $formattedTree); return $this->view->fetch(); } @@ -471,4 +504,196 @@ ORDER BY distance;",[$order->lng,$order->lat]); $this->error(__('No rows were deleted')); } + 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'); + $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['item_id']); + + unset($filter['area_id']); + + $op = (array)json_decode($op, true); + $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]; + } + } diff --git a/application/admin/validate/Order.php b/application/admin/validate/Order.php index e4286fa..4a02764 100644 --- a/application/admin/validate/Order.php +++ b/application/admin/validate/Order.php @@ -12,7 +12,7 @@ class Order extends Validate protected $rule = [ 'source' => 'require', 'item_id' => 'require', - 'customer' => 'require|max:32', + 'customer' => 'max:32', 'tel' => 'require|number|max:32|regex:/^1[3-9]\d{9}$/', 'area_id' => 'require', 'address' => 'require|max:255', @@ -28,7 +28,6 @@ class Order extends Validate 'source.require' => '请选择订单渠道', 'item_id.require' => '请选择服务项目', - 'customer.require' => '请输入客户昵称', 'customer.max' => '客户昵称不能超过 32 个字符', 'tel.require' => '请输入客户电话', diff --git a/application/admin/view/order/add.html b/application/admin/view/order/add.html index 221e82b..a7afe2e 100644 --- a/application/admin/view/order/add.html +++ b/application/admin/view/order/add.html @@ -24,7 +24,7 @@