where($field, $params[$field]); } } // 关键词(模糊搜索) if (!empty($params['searchKeyword'])) { $query->where(function ($q) use ($params) { $q->where('website', 'like', '%' . $params['searchKeyword'] . '%') ->whereOr('remark', 'like', '%' . $params['searchKeyword'] . '%'); }); } $list = $query->order('create_time', $order) ->hidden(['ticketStaff', 'ticketCompany', 'ticketOperator', 'company_id', 'operator_id', 'user_id']) ->append(['username', 'company_name', 'operator_name']) ->paginate( $limit, false, [ 'page' => $page, 'query' => $params ] ); return $list; } /** * 新增工单 * */ public function createTicket($data) { if (empty($data['website'])) { throw new \Exception('网站不能为空'); } $website = trim($data['website']); // 并发锁 $lockKey = 'create_ticket_lock_' . md5($website); if (Cache::has($lockKey)) { throw new \Exception('当前该网址正在被创建工单中,请稍后重试'); } Cache::set($lockKey, 1, 5); // 锁定5秒 try { // 查找是否有未完成的同网站工单 $unfinishedTicket = Tickets::where('website', $website) ->whereIn('status', [0, 1]) ->find(); if ($unfinishedTicket) { Cache::delete($lockKey); throw new \Exception('已存在未完成的同网站工单,无法创建'); } // 当前无相同网站 $ticketResult = Tickets::create($data); // 通知前端实时刷新(静默,广播服务不可用不影响主流程) TicketNotifier::notify($ticketResult->id, 'create'); return $ticketResult; } catch (\Exception $e) { Cache::delete($lockKey); throw $e; } } /** * 更新工单 * @param $id 工单id * @param $data 外部传入的更新数据 * @param $uid 当前登录用户id * @param $role 当前登录用户角色 * @return array */ public function updateTicket($id, $data, $allowFields, $isRole, $isSuper = false) { $ticket = Tickets::where('id', $id)->find(); if (!$ticket) { throw new \Exception('工单不存在'); } // 提取 $allowFields 允许修改的字段 $updateData = []; foreach ($allowFields as $field) { if (array_key_exists($field, $data)) { $updateData[$field] = $data[$field]; } } // 如果没有有效数据需要更新 if (empty($updateData)) { throw new \Exception('没有合法的更新字段'); } return $ticket->save($updateData); } /** * 获取所有运营人员名称 (下拉筛选用)-仅限后台使用 * */ public function getAllOperators() { $operators = CompanyOperators::with('company')->select(); $operators->each(function ($item) { $item->hidden(['company_id', 'company', 'create_time', 'status']); $item->append(['company_name']); return $item; }); return $operators; } public function TestgetAllOperators() { $operators = Companys::with('companyoperators')->select(); return $operators; } /** * 统计各状态工单数量 */ public function getTicketDashboardStats() { return [ 'total' => Tickets::count(), 'status_counts' => Tickets::field('status, COUNT(*) as count') ->group('status') ->select() ]; } /** * 批量更新工单(事务内执行) */ public function batchUpdateTickets(array $ids, array $data, array $allowFields, $uid, $isSuper = false) { if (empty($ids)) { throw new \Exception('请选择要更新的工单'); } $updateData = []; foreach ($allowFields as $field) { if (array_key_exists($field, $data)) { $updateData[$field] = $data[$field]; } } if (empty($updateData)) { throw new \Exception('没有合法的更新字段'); } $tickets = Tickets::whereIn('id', $ids)->select(); if ($tickets->isEmpty()) { throw new \Exception('未找到任何工单'); } \think\facade\Db::transaction(function () use ($tickets, $updateData, $uid, $isSuper) { foreach ($tickets as $ticket) { if (!$isSuper) { if (!is_null($ticket->user_id) && $ticket->user_id != $uid) { throw new \Exception("工单 #{$ticket->id} 没有权限修改"); } } $ticket->save($updateData); } }); return ['updated_count' => count($tickets)]; } public function getStaffList() { $map = [ 'role' => ['user', 'admin'], 'status' => 1 ]; $staffs = User::where($map)->field('id, username', 'real_name')->select(); return $staffs; } }