From 460de929127f0adf076b705e2edf9b115e09c3ed Mon Sep 17 00:00:00 2001 From: mzl Date: Wed, 10 Dec 2025 17:23:59 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=B4=BE=E5=8D=A1=E7=A4=BE=E5=AA=92?= =?UTF-8?q?=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/inquiry/command/AssignInquiryCommand.php | 145 ++++++++++ .../command/FbLeadToInquiryCommand.php | 164 +++++++++++ app/inquiry/command/ImportFbCommand.php | 256 ++++++++++++++++++ app/inquiry/utils/FbLeadHeaderMapper.php | 154 +++++++++++ app/inquiry/utils/PhoneCountryHelper.php | 58 ++++ app/inquiry/utils/RoundRobinAssigner.php | 46 ++++ 6 files changed, 823 insertions(+) create mode 100644 app/inquiry/command/AssignInquiryCommand.php create mode 100644 app/inquiry/command/FbLeadToInquiryCommand.php create mode 100644 app/inquiry/command/ImportFbCommand.php create mode 100644 app/inquiry/utils/FbLeadHeaderMapper.php create mode 100644 app/inquiry/utils/PhoneCountryHelper.php create mode 100644 app/inquiry/utils/RoundRobinAssigner.php diff --git a/app/inquiry/command/AssignInquiryCommand.php b/app/inquiry/command/AssignInquiryCommand.php new file mode 100644 index 0000000..f743335 --- /dev/null +++ b/app/inquiry/command/AssignInquiryCommand.php @@ -0,0 +1,145 @@ + $v > 0 + )); + + if (empty($userIds)) { + throw new BusinessException('SALES_USER_IDS 业务员列表不能为空,请先在命令中配置.'); + } + + // 取出“待分配”的询盘(你可以根据自己系统调整条件) + // 当前策略:status = 0 且 recipient = 0 的视为未分配 + $inquiries = Db::table('inquiry_log') + ->where('enter_user_id', 186) + ->where('channel', 10) + ->where('status', 0) + ->where('recipient', 0) + ->where('id', '>', 34426) + ->orderBy('id') + ->limit(static::BATCH_LIMIT) + ->get(); + + if ($inquiries->isEmpty()) { + $output->writeln('没有需要分配的询盘(status=0 且 recipient=0)'); + return self::SUCCESS; + } + + $now = time(); + $count = 0; + + foreach ($inquiries as $row) { + $inquiryId = (int)$row->id; + + // 轮询取出一个业务员 ID + $recipientUserId = $this->nextRecipientId($userIds, static::ROUND_ROBIN_GROUP_KEY); + + // 对每一条记录单独事务,避免单条异常拖垮全部 + Db::transaction(function () use ($inquiryId, $recipientUserId, $now, $output, &$count) { + // 1)更新 inquiry_log + $affected = Db::table('inquiry_log') + ->where('id', $inquiryId) + ->update([ + 'recipient' => $recipientUserId, + 'status' => 2, + 'r_time' => $now, + 't_time' => $now, + 'updated_at' => $now, + ]); + + if ($affected === 0) { + // 被其他进程抢先更新也有可能,这里只打印提示不中断整个批次 + $output->writeln("询盘 {$inquiryId} 未更新(可能已被处理)"); + return; + } + + // 2)构造队列 payload(后续 CRM 消费时至少知道 ID) + $res = [ + 'id' => $inquiryId, + 'recipient' => $recipientUserId, + 'dispatched_at' => $now, + 'source' => 'fb_leads_inquiry', + ]; + + // 3)推送到 CRM 队列 + RedisQueueRedis::send('inquiry-to-crm-new', $res); + + $count++; + $output->writeln("已分配询盘 {$inquiryId} 给业务员 {$recipientUserId},并推送到队列"); + }); + } + + $output->writeln("本次共分配成功 {$count} 条询盘"); + + return self::SUCCESS; + } + + /** + * 轮询获取“下一位业务员 ID” + * + * @param int[] $userIds + * @param string $groupKey + * @return int + * @throws BusinessException + */ + protected function nextRecipientId(array $userIds, string $groupKey = 'default'): int + { + $userIds = array_values(array_filter(array_map('intval', $userIds), fn($v) => $v > 0)); + if (empty($userIds)) { + throw new BusinessException('轮询分配失败:业务员列表为空'); + } + + $count = count($userIds); + $key = 'inquiry:assign:round_robin:' . $groupKey; + + // Redis INCR 是原子操作,适合并发下使用 + $val = Redis::incr($key); // 第一次会从 0 变成 1 + + // 换算为从 0 开始的下标 + $index = ($val - 1) % $count; + + return $userIds[$index]; + } +} diff --git a/app/inquiry/command/FbLeadToInquiryCommand.php b/app/inquiry/command/FbLeadToInquiryCommand.php new file mode 100644 index 0000000..424417a --- /dev/null +++ b/app/inquiry/command/FbLeadToInquiryCommand.php @@ -0,0 +1,164 @@ +where('sync_status', 0) + ->get(); + + if ($leads->isEmpty()) { + $output->writeln('没有需要同步的 fb_leads(sync_status = 0)'); + return self::SUCCESS; + } + + $now = time(); + + Db::transaction(function () use ($leads, $now, $output) { + $insert = []; + $ids = []; + + foreach ($leads as $lead) { + $leadArr = (array)$lead; + $insert[] = $this->mapLeadToInquiry($leadArr, $now); + // 假设 fb_leads 的主键字段名为 id + $ids[] = $leadArr['id']; + } + + if ($insert) { + // 1) 写入 inquiry_log + Db::table('inquiry_log')->insert($insert); + + // 2) 回写 fb_leads 的同步状态 + Db::table('fb_leads') + ->whereIn('id', $ids) + ->update([ + 'sync_status' => 1, + 'updated_at' => $now, + ]); + + $output->writeln('已导入 ' . count($insert) . ' 条数据到 inquiry_log,并更新 fb_leads.sync_status = 1'); + } + }); + + return self::SUCCESS; + } + + /** + * 将一条 fb_leads 记录映射为 inquiry_log 记录 + */ + protected function mapLeadToInquiry(array $lead, int $now): array + { + // 联系方式 + $email = (string)($lead['email'] ?? ''); + $tel = (string)($lead['phone'] ?? ''); + $wa = $tel; // 先用电话号码当 WhatsApp + + // 根据电话或 WhatsApp 区号识别国家 + $countryId = PhoneCountryHelper::detectCountryId($tel ?: $wa); + + // 所有默认值按你的要求设置 + $data = [ + 'order_no' => $this->orderNum(), + 'enter_user_id' => static::DEFAULT_ENTER_USER_ID, + 'recipient' => 0, + 'quality' => 2, + 'channel' => static::DEFAULT_CHANNEL, + + 'email' => $email, + 'tel' => $tel, + 'whatsapp' => $wa, + 'country' => $countryId ?: 0, + 'contacts' => (string)($lead['full_name'] ?? ''), + + 'content' => $this->buildContentHtml($lead), + + 'status' => 0, + 'r_time' => 0, + 't_time' => 0, + 'sync_crm' => 0, + + 'created_at' => $now, + 'updated_at' => $now, + ]; + + return $data; + } + + /** + * 生成订单号 + */ + protected function orderNum(): string + { + return 'SN' . date('Ymd') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT); + } + + /** + * 根据 fb_leads 的字段拼出富文本内容 + */ + protected function buildContentHtml(array $lead): string + { + $e = function ($v) { + return htmlspecialchars((string)$v, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); + }; + + $lines = []; + + if (!empty($lead['car_model'])) { + $lines[] = '

意向车型:' . $e($lead['car_model']) . '

'; + } + if (!empty($lead['car_quantity']) || !empty($lead['car_quantity_text'])) { + $qty = $lead['car_quantity'] ?? $lead['car_quantity_text'] ?? ''; + $lines[] = '

意向数量:' . $e($qty) . '

'; + } + if (!empty($lead['favorite_color'])) { + $lines[] = '

意向颜色:' . $e($lead['favorite_color']) . '

'; + } + if (!empty($lead['usage_type'])) { + $lines[] = '

用途:' . $e($lead['usage_type']) . '

'; + } + if (!empty($lead['seat_preference'])) { + $lines[] = '

座位数偏好:' . $e($lead['seat_preference']) . '

'; + } + + $lines[] = '
'; + $lines[] = '

广告与表单信息:

'; + $lines[] = '

平台:' . $e($lead['platform'] ?? '') . '

'; + $lines[] = '

Campaign:' . $e($lead['campaign_name'] ?? '') . ' (#' . $e($lead['campaign_id'] ?? '') . ')

'; + $lines[] = '

Adset:' . $e($lead['adset_name'] ?? '') . ' (#' . $e($lead['adset_id'] ?? '') . ')

'; + $lines[] = '

Ad:' . $e($lead['ad_name'] ?? '') . ' (#' . $e($lead['ad_id'] ?? '') . ')

'; + $lines[] = '

Form:' . $e($lead['form_name'] ?? '') . ' (#' . $e($lead['form_id'] ?? '') . ')

'; + + $lines[] = '
'; + $lines[] = '

Meta 信息:

'; + $lines[] = '

Lead ID:' . $e($lead['fb_lead_id'] ?? '') . '

'; + $lines[] = '

FB 创建时间原始值:' . $e($lead['fb_created_time'] ?? '') . '

'; + + if (!empty($lead['inbox_url'])) { + $url = $e($lead['inbox_url']); + $lines[] = '

Inbox 链接:' . $url . '

'; + } + + return implode("\n", $lines); + } +} diff --git a/app/inquiry/command/ImportFbCommand.php b/app/inquiry/command/ImportFbCommand.php new file mode 100644 index 0000000..1e11d34 --- /dev/null +++ b/app/inquiry/command/ImportFbCommand.php @@ -0,0 +1,256 @@ +addOption( + 'file', + null, + InputOption::VALUE_OPTIONAL, + '要导入的单个 Excel 文件名(相对 public/excel 的路径,或绝对路径)' + ) + ->addOption( + 'dir', + null, + InputOption::VALUE_OPTIONAL, + 'Excel 目录(相对 public/ 的路径)', + 'excel' // 默认就是 public/excel + ); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $fileOption = $input->getOption('file'); + $dirOption = $input->getOption('dir') ?? 'excel'; + + // 基准目录:public/{$dirOption} + $baseDir = rtrim(public_path($dirOption), DIRECTORY_SEPARATOR); + + if ($fileOption) { + // 如果传的是绝对路径,直接用;否则认为是相对 baseDir 的文件名 + if ($this->isAbsolutePath($fileOption)) { + $filePath = $fileOption; + } else { + $filePath = $baseDir . DIRECTORY_SEPARATOR . $fileOption; + } + + $output->writeln("开始导入单个文件: {$filePath}"); + + $this->importOneFile($filePath, $output); + } else { + // 不指定 file 时,默认导入目录下所有 .xlsx + if (!is_dir($baseDir)) { + throw new BusinessException("目录不存在:{$baseDir}"); + } + + $pattern = $baseDir . DIRECTORY_SEPARATOR . '*.xlsx'; + $files = glob($pattern); + + if (empty($files)) { + $output->writeln("目录 {$baseDir} 下没有找到 .xlsx 文件"); + return self::SUCCESS; + } + + $output->writeln("开始批量导入目录: {$baseDir}"); + foreach ($files as $filePath) { + $output->writeln(" -> 文件:{$filePath}"); + try { + $this->importOneFile($filePath, $output); + $output->writeln(" 导入成功"); + } catch (\Throwable $e) { + // 某个文件失败,不影响后面的文件 + $output->writeln(" 导入失败:{$e->getMessage()}"); + } + } + } + + return self::SUCCESS; + } + + /** + * 导入单个 Excel 文件 + */ + protected function importOneFile(string $filePath, OutputInterface $output): void + { + if (!is_file($filePath)) { + throw new BusinessException("文件不存在:{$filePath}"); + } + + $spreadsheet = IOFactory::load($filePath); + $sheet = $spreadsheet->getActiveSheet(); + $rows = $sheet->toArray(null, true, true, true); + + if (empty($rows)) { + throw new BusinessException('Excel 内容为空:' . $filePath); + } + + // 取第一行表头 + $headerRow = array_shift($rows); + + // 表头映射器 + $mapper = new FbLeadHeaderMapper(); + + // 如果有未知表头,这里会直接抛异常中断当前文件 + $colToField = $mapper->buildColumnFieldMap($headerRow); + + $insertData = []; + $now = time(); + + foreach ($rows as $row) { + $item = []; + + foreach ($colToField as $colIndex => $field) { + $raw = $row[$colIndex] ?? null; + + switch ($field) { + // 1) is_organic: Excel 里是 true/false,这里转成 0/1 + case 'is_organic': + $item['is_organic'] = $this->normalizeIsOrganic($raw); + break; + + // 2) fb_created_time: 统一转成 Y-m-d H:i:s + case 'fb_created_time': + $item['fb_created_time'] = $this->normalizeFbCreatedTime($raw); + break; + + default: + if (is_string($raw)) { + $raw = trim($raw); + } + $item[$field] = $raw; + break; + } + } + + // 补充公共字段 + $item['source_file'] = basename($filePath); + $item['created_at'] = $now; + $item['updated_at'] = $now; + + // 整行都空就跳过 + $allNull = true; + foreach ($item as $v) { + if ($v !== null && $v !== '') { + $allNull = false; + break; + } + } + if ($allNull) { + continue; + } + + $insertData[] = $item; + } + + if ($insertData) { + Db::table('fb_leads')->insert($insertData); + } else { + $output->writeln(" 文件 {$filePath} 没有有效数据行"); + } + } + + /** + * 将 Excel 里的 is_organic 值转换为 0/1 + */ + protected function normalizeIsOrganic($value): int + { + if ($value === null) { + return 0; + } + + $v = strtolower(trim((string)$value)); + + // 认为这些是 “true” + $trueValues = ['1', 'true', 'yes', 'y']; + + return in_array($v, $trueValues, true) ? 1 : 0; + } + + /** + * 统一处理 fb_created_time + * Excel 目前是类似 '12/8/25',这里尽量转成 'Y-m-d H:i:s' + * 解析失败时返回 null + */ + protected function normalizeFbCreatedTime($value): ?string + { + if ($value === null || $value === '') { + return null; + } + + if ($value instanceof \DateTimeInterface) { + return $value->format('Y-m-d H:i:s'); + } + + $v = trim((string)$value); + + $formats = [ + 'Y-m-d H:i:s', + 'Y-m-d', + 'n/j/y', // 12/8/25 + 'n/j/Y', + 'd/m/Y', + 'd.m.Y', + ]; + + foreach ($formats as $fmt) { + $dt = \DateTime::createFromFormat($fmt, $v); + if ($dt !== false) { + return $dt->format('Y-m-d H:i:s'); + } + } + + // 纯数字当时间戳试一下 + if (is_numeric($v) && strlen($v) >= 9 && strlen($v) <= 11) { + $ts = (int)$v; + if ($ts > 0) { + return date('Y-m-d H:i:s', $ts); + } + } + + return null; + } + + /** + * 判断是否为绝对路径(简单兼容 Windows / Linux) + */ + protected function isAbsolutePath(string $path): bool + { + // Windows: X:\ 或 \\server\share + if (preg_match('/^[a-zA-Z]:\\\\/', $path) || str_starts_with($path, '\\\\')) { + return true; + } + + // *nix: / 开头 + return str_starts_with($path, '/'); + } +} + +/* + +php webman tb-db +# 等价于 php webman tb-db --dir=excel +# 会遍历 public/excel/*.xlsx 逐个导入 + +# 相对路径(相对 public/excel) +php webman tb-db --file="BYD tang_Leads_2025-12-04_2025-12-09.xlsx" + +# 或给绝对路径 +php webman tb-db --file="/www/wwwroot/xxx/public/excel/BYD tang_Leads_2025-12-04_2025-12-09.xlsx" + +*/ \ No newline at end of file diff --git a/app/inquiry/utils/FbLeadHeaderMapper.php b/app/inquiry/utils/FbLeadHeaderMapper.php new file mode 100644 index 0000000..59b1cb5 --- /dev/null +++ b/app/inquiry/utils/FbLeadHeaderMapper.php @@ -0,0 +1,154 @@ + DB 字段名 + * 注意:key 用的是“原始表头字符串”(包括下划线) + */ + protected array $headerMap = [ + // ===== 基础公共字段 ===== + 'id' => 'fb_lead_id', + 'created_time' => 'fb_created_time', + 'ad_id' => 'ad_id', + 'ad_name' => 'ad_name', + 'adset_id' => 'adset_id', + 'adset_name' => 'adset_name', + 'campaign_id' => 'campaign_id', + 'campaign_name' => 'campaign_name', + 'form_id' => 'form_id', + 'form_name' => 'form_name', + 'is_organic' => 'is_organic', + 'platform' => 'platform', + + 'full_name' => 'full_name', + 'phone' => 'phone', + 'phone_number' => 'phone', // 兼容写法 + 'email' => 'email', + 'lead_status' => 'lead_status', + 'inbox_url' => 'inbox_url', + + // ===== 车型相关:全部归到 car_model ===== + 'which_model_of_this_car_would_you_like_to_purchase?_' => 'car_model', + 'which_model_of_this_car_would_you_like_to_purchase?' => 'car_model', + 'which_car_model_would_you_like_to_purchase?' => 'car_model', + 'which_model_do_you_want_to_purchase?' => 'car_model', + 'which_model_would_you_like_to_purchase?' => 'car_model', + 'which_version_do_you_want_to_buy?' => 'car_model', // 这里也归到车型/版本字段 + + // ===== 数量相关:全部归到 car_quantity ===== + 'how_many_cars_would_you_like_to_buy?_' => 'car_quantity', + 'how_many_cars_would_you_like_to_buy?' => 'car_quantity', + '_how_many_cars_would_you_like_to_buy?' => 'car_quantity', + 'how_many_cars_do_you_buy?' => 'car_quantity', + 'how_many_cars_do_you_want_to_purchase?' => 'car_quantity', + 'how_many_cars_do_you_want_to_buy?' => 'car_quantity', + 'what_quantity_do_you_want_to_buy?' => 'car_quantity', + + // ===== 颜色相关:归到 favorite_color ===== + 'what_color_do_you_like?' => 'favorite_color', + 'which_color_would_you_like_to_purchase?' => 'favorite_color', + + // ===== 用途相关:归到 usage_type ===== + 'are_you_using_it_for_business_or_personal_use?' => 'usage_type', + 'business_use_or_personal_use?' => 'usage_type', + 'personal_use_or_business_use?' => 'usage_type', + + // ===== 座位数相关 ===== + 'do_you_want_to_buy_six_seats_or_seven_seats?' => 'seat_preference', + ]; + + /** + * 返回所有支持的 Excel 表头 + */ + public function getSupportedHeaders(): array + { + return array_keys($this->headerMap); + } + + /** + * 单个表头映射:原始表头 -> DB 字段名 + */ + public function mapHeader(string $rawHeader): ?string + { + $key = $this->normalizeHeader($rawHeader); + + return $this->headerMap[$key] ?? null; + } + + /** + * 校验一整行表头: + * - 有任何不认识的表头,就抛 BusinessException + */ + public function validateHeaders(array $rawHeaders): void + { + $unsupported = []; + + foreach ($rawHeaders as $header) { + $header = (string)$header; + $key = $this->normalizeHeader($header); + + // 允许空表头(多余空列) + if ($key === '') { + continue; + } + + if (!isset($this->headerMap[$key])) { + $unsupported[] = $header; + } + } + + if (!empty($unsupported)) { + $msg = 'Excel 表头包含未兼容字段:' . implode('、', $unsupported) + . '。请检查这些字段是否需要加入映射配置。'; + throw new BusinessException($msg); + } + } + + /** + * 根据第一行表头,构建 “列索引 => DB 字段” 映射 + */ + public function buildColumnFieldMap(array $rawHeaders): array + { + // 先做一遍校验(发现问题直接抛异常) + $this->validateHeaders($rawHeaders); + + $colToField = []; + + foreach ($rawHeaders as $index => $header) { + $key = $this->normalizeHeader((string)$header); + if ($key === '') { + continue; + } + + $field = $this->headerMap[$key] ?? null; + if ($field === null) { + continue; // 理论上不会到这儿,双保险 + } + + $colToField[$index] = $field; + } + + return $colToField; + } + + /** + * 表头标准化: + * 目前只去 BOM + trim,保持和 headerMap 中 key 完全一致 + * 如果后面再出现“有空格/大小写”的版本,我们可以在这里做 strtolower / 替换空格 为 _ + */ + protected function normalizeHeader(string $header): string + { + // 去掉 UTF-8 BOM + $header = preg_replace('/^\xEF\xBB\xBF/', '', $header); + + // 去掉前后空白 + $header = trim($header); + + return $header; + } +} diff --git a/app/inquiry/utils/PhoneCountryHelper.php b/app/inquiry/utils/PhoneCountryHelper.php new file mode 100644 index 0000000..78ec4ab --- /dev/null +++ b/app/inquiry/utils/PhoneCountryHelper.php @@ -0,0 +1,58 @@ + + + if (str_starts_with($phone, '00')) { + $phone = '+' . substr($phone, 2); + } elseif ($phone[0] !== '+') { + // 没有 +,默认补一个(大多数线索都是国际号) + $phone = '+' . $phone; + } + + $digits = ltrim($phone, '+'); + if ($digits === '') { + return null; + } + + // 3. 国家区号最长 3 位,从长到短匹配 + for ($len = 3; $len >= 1; $len--) { + $code = substr($digits, 0, $len); + if ($code === '') { + continue; + } + + $country = Db::table('country') + ->where('phone_code', $code) + ->first(); + + if ($country) { + return (int)$country->id; + } + } + + // 没找到 + return null; + } +} diff --git a/app/inquiry/utils/RoundRobinAssigner.php b/app/inquiry/utils/RoundRobinAssigner.php new file mode 100644 index 0000000..5063884 --- /dev/null +++ b/app/inquiry/utils/RoundRobinAssigner.php @@ -0,0 +1,46 @@ + $v > 0)); + if (empty($userIds)) { + throw new BusinessException('轮询分配业务员失败:业务员列表不能为空'); + } + + $count = count($userIds); + + // Redis key:同一个 groupKey 共用一条轮询链 + $key = self::REDIS_KEY_PREFIX . $groupKey; + + // 使用 INCR 做自增计数,天然是原子操作,适合并发环境 + // 第一次调用 INCR 返回 1,我们用 (value - 1) 来做索引,从 0 开始 + $val = Redis::incr($key); // 如果不存在,Redis 会先置为 0 再加 1 + + $index = ($val - 1) % $count; + + return $userIds[$index]; + } +} From ba7c00e9427da3438282874874a495018141d650 Mon Sep 17 00:00:00 2001 From: mzl Date: Wed, 10 Dec 2025 12:15:17 +0000 Subject: [PATCH 2/2] inquiry --- .gitignore | 2 + .../InquiryAssignInquiryCommand.php} | 32 +- .../InquiryFbLeadCommand.php} | 8 +- .../InquiryImportFbCommand.php} | 8 +- app/inquiry/utils/FbLeadHeaderMapper.php | 2 +- app/inquiry/utils/PhoneCountryHelper.php | 2 +- app/inquiry/utils/RoundRobinAssigner.php | 2 +- composer.json | 3 +- composer.lock | 711 ++++++++++-------- config/plugin/webman/log/app.php | 19 + config/plugin/webman/log/middleware.php | 21 + 11 files changed, 482 insertions(+), 328 deletions(-) rename app/{inquiry/command/AssignInquiryCommand.php => command/InquiryAssignInquiryCommand.php} (91%) rename app/{inquiry/command/FbLeadToInquiryCommand.php => command/InquiryFbLeadCommand.php} (97%) rename app/{inquiry/command/ImportFbCommand.php => command/InquiryImportFbCommand.php} (97%) create mode 100644 config/plugin/webman/log/app.php create mode 100644 config/plugin/webman/log/middleware.php diff --git a/.gitignore b/.gitignore index 92bf9b0..224ad2d 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ /windows.php /bootstrap.php /composer.lock +.env_copy +/public/excel \ No newline at end of file diff --git a/app/inquiry/command/AssignInquiryCommand.php b/app/command/InquiryAssignInquiryCommand.php similarity index 91% rename from app/inquiry/command/AssignInquiryCommand.php rename to app/command/InquiryAssignInquiryCommand.php index f743335..adb8309 100644 --- a/app/inquiry/command/AssignInquiryCommand.php +++ b/app/command/InquiryAssignInquiryCommand.php @@ -1,6 +1,6 @@ id; - + sleep(1); // 轮询取出一个业务员 ID $recipientUserId = $this->nextRecipientId($userIds, static::ROUND_ROBIN_GROUP_KEY); diff --git a/app/inquiry/command/FbLeadToInquiryCommand.php b/app/command/InquiryFbLeadCommand.php similarity index 97% rename from app/inquiry/command/FbLeadToInquiryCommand.php rename to app/command/InquiryFbLeadCommand.php index 424417a..aec2199 100644 --- a/app/inquiry/command/FbLeadToInquiryCommand.php +++ b/app/command/InquiryFbLeadCommand.php @@ -1,8 +1,8 @@ =5.3" @@ -59,16 +53,16 @@ }, { "name": "brick/math", - "version": "0.14.0", + "version": "0.14.1", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "113a8ee2656b882d4c3164fa31aa6e12cbb7aaa2" + "reference": "f05858549e5f9d7bb45875a75583240a38a281d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/113a8ee2656b882d4c3164fa31aa6e12cbb7aaa2", - "reference": "113a8ee2656b882d4c3164fa31aa6e12cbb7aaa2", + "url": "https://api.github.com/repos/brick/math/zipball/f05858549e5f9d7bb45875a75583240a38a281d0", + "reference": "f05858549e5f9d7bb45875a75583240a38a281d0", "shasum": "" }, "require": { @@ -107,7 +101,7 @@ ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.14.0" + "source": "https://github.com/brick/math/tree/0.14.1" }, "funding": [ { @@ -115,7 +109,7 @@ "type": "github" } ], - "time": "2025-08-29T12:40:03+00:00" + "time": "2025-11-24T14:40:29+00:00" }, { "name": "carbonphp/carbon-doctrine-types", @@ -420,31 +414,31 @@ }, { "name": "fruitcake/php-cors", - "version": "v1.3.0", + "version": "v1.4.0", "source": { "type": "git", "url": "https://github.com/fruitcake/php-cors.git", - "reference": "3d158f36e7875e2f040f37bc0573956240a5a38b" + "reference": "38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/3d158f36e7875e2f040f37bc0573956240a5a38b", - "reference": "3d158f36e7875e2f040f37bc0573956240a5a38b", + "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379", + "reference": "38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379", "shasum": "" }, "require": { - "php": "^7.4|^8.0", - "symfony/http-foundation": "^4.4|^5.4|^6|^7" + "php": "^8.1", + "symfony/http-foundation": "^5.4|^6.4|^7.3|^8" }, "require-dev": { - "phpstan/phpstan": "^1.4", + "phpstan/phpstan": "^2", "phpunit/phpunit": "^9", - "squizlabs/php_codesniffer": "^3.5" + "squizlabs/php_codesniffer": "^4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2-dev" + "dev-master": "1.3-dev" } }, "autoload": { @@ -475,7 +469,7 @@ ], "support": { "issues": "https://github.com/fruitcake/php-cors/issues", - "source": "https://github.com/fruitcake/php-cors/tree/v1.3.0" + "source": "https://github.com/fruitcake/php-cors/tree/v1.4.0" }, "funding": [ { @@ -487,7 +481,7 @@ "type": "github" } ], - "time": "2023-10-12T05:21:21+00:00" + "time": "2025-12-03T09:33:47+00:00" }, { "name": "graham-campbell/result-type", @@ -964,16 +958,16 @@ }, { "name": "illuminate/bus", - "version": "v12.37.0", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/bus.git", - "reference": "797f768b7a52fb98443b8127cda71840cc2dbc5b" + "reference": "fdb568a20ad96461caa83b98ffc36d9e95894491" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/bus/zipball/797f768b7a52fb98443b8127cda71840cc2dbc5b", - "reference": "797f768b7a52fb98443b8127cda71840cc2dbc5b", + "url": "https://api.github.com/repos/illuminate/bus/zipball/fdb568a20ad96461caa83b98ffc36d9e95894491", + "reference": "fdb568a20ad96461caa83b98ffc36d9e95894491", "shasum": "" }, "require": { @@ -1013,20 +1007,20 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-10-30T12:22:29+00:00" + "time": "2025-11-30T17:14:13+00:00" }, { "name": "illuminate/collections", - "version": "v12.37.0", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/collections.git", - "reference": "deb291b109b6f7fd776a3550a120771137b3c5d1" + "reference": "16657effa6a5a4e728f9aeb3e38fb4fa9ba70e7d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/collections/zipball/deb291b109b6f7fd776a3550a120771137b3c5d1", - "reference": "deb291b109b6f7fd776a3550a120771137b3c5d1", + "url": "https://api.github.com/repos/illuminate/collections/zipball/16657effa6a5a4e728f9aeb3e38fb4fa9ba70e7d", + "reference": "16657effa6a5a4e728f9aeb3e38fb4fa9ba70e7d", "shasum": "" }, "require": { @@ -1072,11 +1066,11 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-10-30T12:22:05+00:00" + "time": "2025-12-06T18:08:25+00:00" }, { "name": "illuminate/conditionable", - "version": "v12.37.0", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/conditionable.git", @@ -1122,20 +1116,21 @@ }, { "name": "illuminate/container", - "version": "v12.37.0", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/container.git", - "reference": "d6eaa8afd48dbe16b6b3c412a87479cad67eeb12" + "reference": "326667a4c813e3ad5a645969a7e3f5c10d159de2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/container/zipball/d6eaa8afd48dbe16b6b3c412a87479cad67eeb12", - "reference": "d6eaa8afd48dbe16b6b3c412a87479cad67eeb12", + "url": "https://api.github.com/repos/illuminate/container/zipball/326667a4c813e3ad5a645969a7e3f5c10d159de2", + "reference": "326667a4c813e3ad5a645969a7e3f5c10d159de2", "shasum": "" }, "require": { "illuminate/contracts": "^12.0", + "illuminate/reflection": "^12.0", "php": "^8.2", "psr/container": "^1.1.1|^2.0.1", "symfony/polyfill-php84": "^1.33", @@ -1179,20 +1174,20 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-09-12T14:35:11+00:00" + "time": "2025-12-08T22:34:25+00:00" }, { "name": "illuminate/contracts", - "version": "v12.37.0", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/contracts.git", - "reference": "5ab717c8f0dd4e84be703796bbb415ccff8de57a" + "reference": "19e8938edb73047017cfbd443b96844b86da4a59" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/contracts/zipball/5ab717c8f0dd4e84be703796bbb415ccff8de57a", - "reference": "5ab717c8f0dd4e84be703796bbb415ccff8de57a", + "url": "https://api.github.com/repos/illuminate/contracts/zipball/19e8938edb73047017cfbd443b96844b86da4a59", + "reference": "19e8938edb73047017cfbd443b96844b86da4a59", "shasum": "" }, "require": { @@ -1227,20 +1222,20 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-10-07T19:59:08+00:00" + "time": "2025-11-26T21:36:01+00:00" }, { "name": "illuminate/database", - "version": "v12.37.0", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/database.git", - "reference": "e42bec6ad999bcc78ce9f3789f5ef937ee2e5982" + "reference": "b44f021fee7b48289312e22fd6e4d580374a86ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/database/zipball/e42bec6ad999bcc78ce9f3789f5ef937ee2e5982", - "reference": "e42bec6ad999bcc78ce9f3789f5ef937ee2e5982", + "url": "https://api.github.com/repos/illuminate/database/zipball/b44f021fee7b48289312e22fd6e4d580374a86ac", + "reference": "b44f021fee7b48289312e22fd6e4d580374a86ac", "shasum": "" }, "require": { @@ -1298,20 +1293,20 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-11-03T14:22:34+00:00" + "time": "2025-12-06T18:08:25+00:00" }, { "name": "illuminate/events", - "version": "v12.37.0", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/events.git", - "reference": "e0de667c68040d59a6ffc09e914536a1186870f0" + "reference": "5fbf9a127cb649699071c2fe98ac1d39e4991da3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/events/zipball/e0de667c68040d59a6ffc09e914536a1186870f0", - "reference": "e0de667c68040d59a6ffc09e914536a1186870f0", + "url": "https://api.github.com/repos/illuminate/events/zipball/5fbf9a127cb649699071c2fe98ac1d39e4991da3", + "reference": "5fbf9a127cb649699071c2fe98ac1d39e4991da3", "shasum": "" }, "require": { @@ -1353,11 +1348,11 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-10-21T15:10:34+00:00" + "time": "2025-12-01T15:02:02+00:00" }, { "name": "illuminate/filesystem", - "version": "v12.37.0", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/filesystem.git", @@ -1424,16 +1419,16 @@ }, { "name": "illuminate/http", - "version": "v12.37.0", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/http.git", - "reference": "5c864f562b2fded08622ee19cd53260aef3db9a0" + "reference": "b7997f2faffb3c31f2a0fa079428ff6bfcce8907" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/http/zipball/5c864f562b2fded08622ee19cd53260aef3db9a0", - "reference": "5c864f562b2fded08622ee19cd53260aef3db9a0", + "url": "https://api.github.com/repos/illuminate/http/zipball/b7997f2faffb3c31f2a0fa079428ff6bfcce8907", + "reference": "b7997f2faffb3c31f2a0fa079428ff6bfcce8907", "shasum": "" }, "require": { @@ -1482,11 +1477,11 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-10-28T14:38:15+00:00" + "time": "2025-12-09T15:25:50+00:00" }, { "name": "illuminate/macroable", - "version": "v12.37.0", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/macroable.git", @@ -1532,16 +1527,16 @@ }, { "name": "illuminate/pagination", - "version": "v12.37.0", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/pagination.git", - "reference": "1d95e70671177108b202e6ceb61bc7bc9924bdbf" + "reference": "87e7e3e7b02d6809b1bcd41782e1ca2c6d2a413b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/pagination/zipball/1d95e70671177108b202e6ceb61bc7bc9924bdbf", - "reference": "1d95e70671177108b202e6ceb61bc7bc9924bdbf", + "url": "https://api.github.com/repos/illuminate/pagination/zipball/87e7e3e7b02d6809b1bcd41782e1ca2c6d2a413b", + "reference": "87e7e3e7b02d6809b1bcd41782e1ca2c6d2a413b", "shasum": "" }, "require": { @@ -1578,11 +1573,11 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-09-02T15:31:06+00:00" + "time": "2025-11-16T14:36:17+00:00" }, { "name": "illuminate/pipeline", - "version": "v12.37.0", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/pipeline.git", @@ -1634,16 +1629,16 @@ }, { "name": "illuminate/redis", - "version": "v12.37.0", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/redis.git", - "reference": "8a397f00036974404d5d4d94eacfe8050af8e7f2" + "reference": "8dc6682638100db9feceaac3db206de752dd0f9a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/redis/zipball/8a397f00036974404d5d4d94eacfe8050af8e7f2", - "reference": "8a397f00036974404d5d4d94eacfe8050af8e7f2", + "url": "https://api.github.com/repos/illuminate/redis/zipball/8dc6682638100db9feceaac3db206de752dd0f9a", + "reference": "8dc6682638100db9feceaac3db206de752dd0f9a", "shasum": "" }, "require": { @@ -1684,11 +1679,62 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-10-26T17:11:19+00:00" + "time": "2025-11-20T20:50:40+00:00" + }, + { + "name": "illuminate/reflection", + "version": "v12.42.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/reflection.git", + "reference": "7b86bc570d5b75e4a3ad79f8cca1491ba24b7c75" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/reflection/zipball/7b86bc570d5b75e4a3ad79f8cca1491ba24b7c75", + "reference": "7b86bc570d5b75e4a3ad79f8cca1491ba24b7c75", + "shasum": "" + }, + "require": { + "illuminate/collections": "^12.0", + "illuminate/contracts": "^12.0", + "php": "^8.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "12.x-dev" + } + }, + "autoload": { + "files": [ + "helpers.php" + ], + "psr-4": { + "Illuminate\\Support\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Reflection package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2025-12-09T15:11:22+00:00" }, { "name": "illuminate/session", - "version": "v12.37.0", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/session.git", @@ -1745,16 +1791,16 @@ }, { "name": "illuminate/support", - "version": "v12.37.0", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/support.git", - "reference": "480df979c8ffe700d6adb6e6e64abe04b32e02e3" + "reference": "d35411be5657e0b5560a5885f3c9140e4cbe0be5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/support/zipball/480df979c8ffe700d6adb6e6e64abe04b32e02e3", - "reference": "480df979c8ffe700d6adb6e6e64abe04b32e02e3", + "url": "https://api.github.com/repos/illuminate/support/zipball/d35411be5657e0b5560a5885f3c9140e4cbe0be5", + "reference": "d35411be5657e0b5560a5885f3c9140e4cbe0be5", "shasum": "" }, "require": { @@ -1766,6 +1812,7 @@ "illuminate/conditionable": "^12.0", "illuminate/contracts": "^12.0", "illuminate/macroable": "^12.0", + "illuminate/reflection": "^12.0", "nesbot/carbon": "^3.8.4", "php": "^8.2", "symfony/polyfill-php83": "^1.33", @@ -1820,7 +1867,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-10-31T16:20:10+00:00" + "time": "2025-12-09T15:26:52+00:00" }, { "name": "jaeger/g-http", @@ -1979,16 +2026,16 @@ }, { "name": "laravel/serializable-closure", - "version": "v2.0.6", + "version": "v2.0.7", "source": { "type": "git", "url": "https://github.com/laravel/serializable-closure.git", - "reference": "038ce42edee619599a1debb7e81d7b3759492819" + "reference": "cb291e4c998ac50637c7eeb58189c14f5de5b9dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/038ce42edee619599a1debb7e81d7b3759492819", - "reference": "038ce42edee619599a1debb7e81d7b3759492819", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/cb291e4c998ac50637c7eeb58189c14f5de5b9dd", + "reference": "cb291e4c998ac50637c7eeb58189c14f5de5b9dd", "shasum": "" }, "require": { @@ -1997,7 +2044,7 @@ "require-dev": { "illuminate/support": "^10.0|^11.0|^12.0", "nesbot/carbon": "^2.67|^3.0", - "pestphp/pest": "^2.36|^3.0", + "pestphp/pest": "^2.36|^3.0|^4.0", "phpstan/phpstan": "^2.0", "symfony/var-dumper": "^6.2.0|^7.0.0" }, @@ -2036,7 +2083,7 @@ "issues": "https://github.com/laravel/serializable-closure/issues", "source": "https://github.com/laravel/serializable-closure" }, - "time": "2025-10-09T13:42:30+00:00" + "time": "2025-11-21T20:52:36+00:00" }, { "name": "league/flysystem", @@ -2515,16 +2562,16 @@ }, { "name": "mpdf/mpdf", - "version": "v8.2.6", + "version": "v8.2.7", "source": { "type": "git", "url": "https://github.com/mpdf/mpdf.git", - "reference": "dd30e3b01061cf8dfe65e7041ab4cc46d8ebdd44" + "reference": "b59670a09498689c33ce639bac8f5ba26721dab3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mpdf/mpdf/zipball/dd30e3b01061cf8dfe65e7041ab4cc46d8ebdd44", - "reference": "dd30e3b01061cf8dfe65e7041ab4cc46d8ebdd44", + "url": "https://api.github.com/repos/mpdf/mpdf/zipball/b59670a09498689c33ce639bac8f5ba26721dab3", + "reference": "b59670a09498689c33ce639bac8f5ba26721dab3", "shasum": "" }, "require": { @@ -2592,7 +2639,7 @@ "type": "custom" } ], - "time": "2025-08-18T08:51:51+00:00" + "time": "2025-12-01T10:18:02+00:00" }, { "name": "mpdf/psr-http-message-shim", @@ -2748,16 +2795,16 @@ }, { "name": "nesbot/carbon", - "version": "3.10.3", + "version": "3.11.0", "source": { "type": "git", "url": "https://github.com/CarbonPHP/carbon.git", - "reference": "8e3643dcd149ae0fe1d2ff4f2c8e4bbfad7c165f" + "reference": "bdb375400dcd162624531666db4799b36b64e4a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/8e3643dcd149ae0fe1d2ff4f2c8e4bbfad7c165f", - "reference": "8e3643dcd149ae0fe1d2ff4f2c8e4bbfad7c165f", + "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/bdb375400dcd162624531666db4799b36b64e4a1", + "reference": "bdb375400dcd162624531666db4799b36b64e4a1", "shasum": "" }, "require": { @@ -2765,9 +2812,9 @@ "ext-json": "*", "php": "^8.1", "psr/clock": "^1.0", - "symfony/clock": "^6.3.12 || ^7.0", + "symfony/clock": "^6.3.12 || ^7.0 || ^8.0", "symfony/polyfill-mbstring": "^1.0", - "symfony/translation": "^4.4.18 || ^5.2.1 || ^6.0 || ^7.0" + "symfony/translation": "^4.4.18 || ^5.2.1 || ^6.0 || ^7.0 || ^8.0" }, "provide": { "psr/clock-implementation": "1.0" @@ -2849,7 +2896,7 @@ "type": "tidelift" } ], - "time": "2025-09-06T13:39:36+00:00" + "time": "2025-12-02T21:04:28+00:00" }, { "name": "nikic/fast-route", @@ -3898,16 +3945,16 @@ }, { "name": "symfony/cache", - "version": "v7.3.6", + "version": "v7.4.1", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "1277a1ec61c8d93ea61b2a59738f1deb9bfb6701" + "reference": "21e0755783bbbab58f2bb6a7a57896d21d27a366" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/1277a1ec61c8d93ea61b2a59738f1deb9bfb6701", - "reference": "1277a1ec61c8d93ea61b2a59738f1deb9bfb6701", + "url": "https://api.github.com/repos/symfony/cache/zipball/21e0755783bbbab58f2bb6a7a57896d21d27a366", + "reference": "21e0755783bbbab58f2bb6a7a57896d21d27a366", "shasum": "" }, "require": { @@ -3915,12 +3962,14 @@ "psr/cache": "^2.0|^3.0", "psr/log": "^1.1|^2|^3", "symfony/cache-contracts": "^3.6", - "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/service-contracts": "^2.5|^3", - "symfony/var-exporter": "^6.4|^7.0" + "symfony/var-exporter": "^6.4|^7.0|^8.0" }, "conflict": { "doctrine/dbal": "<3.6", + "ext-redis": "<6.1", + "ext-relay": "<0.12.1", "symfony/dependency-injection": "<6.4", "symfony/http-kernel": "<6.4", "symfony/var-dumper": "<6.4" @@ -3935,13 +3984,13 @@ "doctrine/dbal": "^3.6|^4", "predis/predis": "^1.1|^2.0", "psr/simple-cache": "^1.0|^2.0|^3.0", - "symfony/clock": "^6.4|^7.0", - "symfony/config": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/filesystem": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/messenger": "^6.4|^7.0", - "symfony/var-dumper": "^6.4|^7.0" + "symfony/clock": "^6.4|^7.0|^8.0", + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/filesystem": "^6.4|^7.0|^8.0", + "symfony/http-kernel": "^6.4|^7.0|^8.0", + "symfony/messenger": "^6.4|^7.0|^8.0", + "symfony/var-dumper": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { @@ -3976,7 +4025,7 @@ "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v7.3.6" + "source": "https://github.com/symfony/cache/tree/v7.4.1" }, "funding": [ { @@ -3996,7 +4045,7 @@ "type": "tidelift" } ], - "time": "2025-10-30T13:22:58+00:00" + "time": "2025-12-04T18:11:45+00:00" }, { "name": "symfony/cache-contracts", @@ -4076,16 +4125,16 @@ }, { "name": "symfony/clock", - "version": "v7.3.0", + "version": "v7.4.0", "source": { "type": "git", "url": "https://github.com/symfony/clock.git", - "reference": "b81435fbd6648ea425d1ee96a2d8e68f4ceacd24" + "reference": "9169f24776edde469914c1e7a1442a50f7a4e110" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/clock/zipball/b81435fbd6648ea425d1ee96a2d8e68f4ceacd24", - "reference": "b81435fbd6648ea425d1ee96a2d8e68f4ceacd24", + "url": "https://api.github.com/repos/symfony/clock/zipball/9169f24776edde469914c1e7a1442a50f7a4e110", + "reference": "9169f24776edde469914c1e7a1442a50f7a4e110", "shasum": "" }, "require": { @@ -4130,7 +4179,7 @@ "time" ], "support": { - "source": "https://github.com/symfony/clock/tree/v7.3.0" + "source": "https://github.com/symfony/clock/tree/v7.4.0" }, "funding": [ { @@ -4141,25 +4190,29 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-09-25T14:21:43+00:00" + "time": "2025-11-12T15:39:26+00:00" }, { "name": "symfony/console", - "version": "v7.3.6", + "version": "v7.4.1", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "c28ad91448f86c5f6d9d2c70f0cf68bf135f252a" + "reference": "6d9f0fbf2ec2e9785880096e3abd0ca0c88b506e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/c28ad91448f86c5f6d9d2c70f0cf68bf135f252a", - "reference": "c28ad91448f86c5f6d9d2c70f0cf68bf135f252a", + "url": "https://api.github.com/repos/symfony/console/zipball/6d9f0fbf2ec2e9785880096e3abd0ca0c88b506e", + "reference": "6d9f0fbf2ec2e9785880096e3abd0ca0c88b506e", "shasum": "" }, "require": { @@ -4167,7 +4220,7 @@ "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.0", "symfony/service-contracts": "^2.5|^3", - "symfony/string": "^7.2" + "symfony/string": "^7.2|^8.0" }, "conflict": { "symfony/dependency-injection": "<6.4", @@ -4181,16 +4234,16 @@ }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/event-dispatcher": "^6.4|^7.0", - "symfony/http-foundation": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/lock": "^6.4|^7.0", - "symfony/messenger": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0", - "symfony/stopwatch": "^6.4|^7.0", - "symfony/var-dumper": "^6.4|^7.0" + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/event-dispatcher": "^6.4|^7.0|^8.0", + "symfony/http-foundation": "^6.4|^7.0|^8.0", + "symfony/http-kernel": "^6.4|^7.0|^8.0", + "symfony/lock": "^6.4|^7.0|^8.0", + "symfony/messenger": "^6.4|^7.0|^8.0", + "symfony/process": "^6.4|^7.0|^8.0", + "symfony/stopwatch": "^6.4|^7.0|^8.0", + "symfony/var-dumper": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { @@ -4224,7 +4277,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.3.6" + "source": "https://github.com/symfony/console/tree/v7.4.1" }, "funding": [ { @@ -4244,7 +4297,7 @@ "type": "tidelift" } ], - "time": "2025-11-04T01:21:42+00:00" + "time": "2025-12-05T15:23:39+00:00" }, { "name": "symfony/deprecation-contracts", @@ -4315,32 +4368,33 @@ }, { "name": "symfony/error-handler", - "version": "v7.3.6", + "version": "v7.4.0", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "bbe40bfab84323d99dab491b716ff142410a92a8" + "reference": "48be2b0653594eea32dcef130cca1c811dcf25c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/bbe40bfab84323d99dab491b716ff142410a92a8", - "reference": "bbe40bfab84323d99dab491b716ff142410a92a8", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/48be2b0653594eea32dcef130cca1c811dcf25c2", + "reference": "48be2b0653594eea32dcef130cca1c811dcf25c2", "shasum": "" }, "require": { "php": ">=8.2", "psr/log": "^1|^2|^3", - "symfony/var-dumper": "^6.4|^7.0" + "symfony/polyfill-php85": "^1.32", + "symfony/var-dumper": "^6.4|^7.0|^8.0" }, "conflict": { "symfony/deprecation-contracts": "<2.5", "symfony/http-kernel": "<6.4" }, "require-dev": { - "symfony/console": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0|^8.0", "symfony/deprecation-contracts": "^2.5|^3", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/serializer": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0|^8.0", + "symfony/serializer": "^6.4|^7.0|^8.0", "symfony/webpack-encore-bundle": "^1.0|^2.0" }, "bin": [ @@ -4372,7 +4426,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v7.3.6" + "source": "https://github.com/symfony/error-handler/tree/v7.4.0" }, "funding": [ { @@ -4392,20 +4446,20 @@ "type": "tidelift" } ], - "time": "2025-10-31T19:12:50+00:00" + "time": "2025-11-05T14:29:59+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v7.3.3", + "version": "v7.4.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "b7dc69e71de420ac04bc9ab830cf3ffebba48191" + "reference": "9dddcddff1ef974ad87b3708e4b442dc38b2261d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b7dc69e71de420ac04bc9ab830cf3ffebba48191", - "reference": "b7dc69e71de420ac04bc9ab830cf3ffebba48191", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9dddcddff1ef974ad87b3708e4b442dc38b2261d", + "reference": "9dddcddff1ef974ad87b3708e4b442dc38b2261d", "shasum": "" }, "require": { @@ -4422,13 +4476,14 @@ }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/error-handler": "^6.4|^7.0", - "symfony/expression-language": "^6.4|^7.0", - "symfony/http-foundation": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/error-handler": "^6.4|^7.0|^8.0", + "symfony/expression-language": "^6.4|^7.0|^8.0", + "symfony/framework-bundle": "^6.4|^7.0|^8.0", + "symfony/http-foundation": "^6.4|^7.0|^8.0", "symfony/service-contracts": "^2.5|^3", - "symfony/stopwatch": "^6.4|^7.0" + "symfony/stopwatch": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { @@ -4456,7 +4511,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v7.3.3" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.4.0" }, "funding": [ { @@ -4476,7 +4531,7 @@ "type": "tidelift" } ], - "time": "2025-08-13T11:49:31+00:00" + "time": "2025-10-28T09:38:46+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -4556,16 +4611,16 @@ }, { "name": "symfony/filesystem", - "version": "v7.3.6", + "version": "v7.4.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "e9bcfd7837928ab656276fe00464092cc9e1826a" + "reference": "d551b38811096d0be9c4691d406991b47c0c630a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/e9bcfd7837928ab656276fe00464092cc9e1826a", - "reference": "e9bcfd7837928ab656276fe00464092cc9e1826a", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/d551b38811096d0be9c4691d406991b47c0c630a", + "reference": "d551b38811096d0be9c4691d406991b47c0c630a", "shasum": "" }, "require": { @@ -4574,7 +4629,7 @@ "symfony/polyfill-mbstring": "~1.8" }, "require-dev": { - "symfony/process": "^6.4|^7.0" + "symfony/process": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { @@ -4602,7 +4657,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.3.6" + "source": "https://github.com/symfony/filesystem/tree/v7.4.0" }, "funding": [ { @@ -4622,27 +4677,27 @@ "type": "tidelift" } ], - "time": "2025-11-05T09:52:27+00:00" + "time": "2025-11-27T13:27:24+00:00" }, { "name": "symfony/finder", - "version": "v7.3.5", + "version": "v7.4.0", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "9f696d2f1e340484b4683f7853b273abff94421f" + "reference": "340b9ed7320570f319028a2cbec46d40535e94bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/9f696d2f1e340484b4683f7853b273abff94421f", - "reference": "9f696d2f1e340484b4683f7853b273abff94421f", + "url": "https://api.github.com/repos/symfony/finder/zipball/340b9ed7320570f319028a2cbec46d40535e94bd", + "reference": "340b9ed7320570f319028a2cbec46d40535e94bd", "shasum": "" }, "require": { "php": ">=8.2" }, "require-dev": { - "symfony/filesystem": "^6.4|^7.0" + "symfony/filesystem": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { @@ -4670,7 +4725,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v7.3.5" + "source": "https://github.com/symfony/finder/tree/v7.4.0" }, "funding": [ { @@ -4690,27 +4745,26 @@ "type": "tidelift" } ], - "time": "2025-10-15T18:45:57+00:00" + "time": "2025-11-05T05:42:40+00:00" }, { "name": "symfony/http-foundation", - "version": "v7.3.6", + "version": "v7.4.1", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "6379e490d6ecfc5c4224ff3a754b90495ecd135c" + "reference": "bd1af1e425811d6f077db240c3a588bdb405cd27" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/6379e490d6ecfc5c4224ff3a754b90495ecd135c", - "reference": "6379e490d6ecfc5c4224ff3a754b90495ecd135c", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/bd1af1e425811d6f077db240c3a588bdb405cd27", + "reference": "bd1af1e425811d6f077db240c3a588bdb405cd27", "shasum": "" }, "require": { "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3.0", - "symfony/polyfill-mbstring": "~1.1", - "symfony/polyfill-php83": "^1.27" + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "^1.1" }, "conflict": { "doctrine/dbal": "<3.6", @@ -4719,13 +4773,13 @@ "require-dev": { "doctrine/dbal": "^3.6|^4", "predis/predis": "^1.1|^2.0", - "symfony/cache": "^6.4.12|^7.1.5", - "symfony/clock": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/expression-language": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/mime": "^6.4|^7.0", - "symfony/rate-limiter": "^6.4|^7.0" + "symfony/cache": "^6.4.12|^7.1.5|^8.0", + "symfony/clock": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/expression-language": "^6.4|^7.0|^8.0", + "symfony/http-kernel": "^6.4|^7.0|^8.0", + "symfony/mime": "^6.4|^7.0|^8.0", + "symfony/rate-limiter": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { @@ -4753,7 +4807,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v7.3.6" + "source": "https://github.com/symfony/http-foundation/tree/v7.4.1" }, "funding": [ { @@ -4773,29 +4827,29 @@ "type": "tidelift" } ], - "time": "2025-11-06T11:05:57+00:00" + "time": "2025-12-07T11:13:10+00:00" }, { "name": "symfony/http-kernel", - "version": "v7.3.6", + "version": "v7.4.2", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "f9a34dc0196677250e3609c2fac9de9e1551a262" + "reference": "f6e6f0a5fa8763f75a504b930163785fb6dd055f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/f9a34dc0196677250e3609c2fac9de9e1551a262", - "reference": "f9a34dc0196677250e3609c2fac9de9e1551a262", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/f6e6f0a5fa8763f75a504b930163785fb6dd055f", + "reference": "f6e6f0a5fa8763f75a504b930163785fb6dd055f", "shasum": "" }, "require": { "php": ">=8.2", "psr/log": "^1|^2|^3", "symfony/deprecation-contracts": "^2.5|^3", - "symfony/error-handler": "^6.4|^7.0", - "symfony/event-dispatcher": "^7.3", - "symfony/http-foundation": "^7.3", + "symfony/error-handler": "^6.4|^7.0|^8.0", + "symfony/event-dispatcher": "^7.3|^8.0", + "symfony/http-foundation": "^7.4|^8.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { @@ -4805,6 +4859,7 @@ "symfony/console": "<6.4", "symfony/dependency-injection": "<6.4", "symfony/doctrine-bridge": "<6.4", + "symfony/flex": "<2.10", "symfony/form": "<6.4", "symfony/http-client": "<6.4", "symfony/http-client-contracts": "<2.5", @@ -4822,27 +4877,27 @@ }, "require-dev": { "psr/cache": "^1.0|^2.0|^3.0", - "symfony/browser-kit": "^6.4|^7.0", - "symfony/clock": "^6.4|^7.0", - "symfony/config": "^6.4|^7.0", - "symfony/console": "^6.4|^7.0", - "symfony/css-selector": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/dom-crawler": "^6.4|^7.0", - "symfony/expression-language": "^6.4|^7.0", - "symfony/finder": "^6.4|^7.0", + "symfony/browser-kit": "^6.4|^7.0|^8.0", + "symfony/clock": "^6.4|^7.0|^8.0", + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/console": "^6.4|^7.0|^8.0", + "symfony/css-selector": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/dom-crawler": "^6.4|^7.0|^8.0", + "symfony/expression-language": "^6.4|^7.0|^8.0", + "symfony/finder": "^6.4|^7.0|^8.0", "symfony/http-client-contracts": "^2.5|^3", - "symfony/process": "^6.4|^7.0", - "symfony/property-access": "^7.1", - "symfony/routing": "^6.4|^7.0", - "symfony/serializer": "^7.1", - "symfony/stopwatch": "^6.4|^7.0", - "symfony/translation": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0|^8.0", + "symfony/property-access": "^7.1|^8.0", + "symfony/routing": "^6.4|^7.0|^8.0", + "symfony/serializer": "^7.1|^8.0", + "symfony/stopwatch": "^6.4|^7.0|^8.0", + "symfony/translation": "^6.4|^7.0|^8.0", "symfony/translation-contracts": "^2.5|^3", - "symfony/uid": "^6.4|^7.0", - "symfony/validator": "^6.4|^7.0", - "symfony/var-dumper": "^6.4|^7.0", - "symfony/var-exporter": "^6.4|^7.0", + "symfony/uid": "^6.4|^7.0|^8.0", + "symfony/validator": "^6.4|^7.0|^8.0", + "symfony/var-dumper": "^6.4|^7.0|^8.0", + "symfony/var-exporter": "^6.4|^7.0|^8.0", "twig/twig": "^3.12" }, "type": "library", @@ -4871,7 +4926,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v7.3.6" + "source": "https://github.com/symfony/http-kernel/tree/v7.4.2" }, "funding": [ { @@ -4891,24 +4946,25 @@ "type": "tidelift" } ], - "time": "2025-11-06T20:58:12+00:00" + "time": "2025-12-08T07:43:37+00:00" }, { "name": "symfony/mime", - "version": "v7.3.4", + "version": "v7.4.0", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "b1b828f69cbaf887fa835a091869e55df91d0e35" + "reference": "bdb02729471be5d047a3ac4a69068748f1a6be7a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/b1b828f69cbaf887fa835a091869e55df91d0e35", - "reference": "b1b828f69cbaf887fa835a091869e55df91d0e35", + "url": "https://api.github.com/repos/symfony/mime/zipball/bdb02729471be5d047a3ac4a69068748f1a6be7a", + "reference": "bdb02729471be5d047a3ac4a69068748f1a6be7a", "shasum": "" }, "require": { "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-intl-idn": "^1.10", "symfony/polyfill-mbstring": "^1.0" }, @@ -4923,11 +4979,11 @@ "egulias/email-validator": "^2.1.10|^3.1|^4", "league/html-to-markdown": "^5.0", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0", - "symfony/property-access": "^6.4|^7.0", - "symfony/property-info": "^6.4|^7.0", - "symfony/serializer": "^6.4.3|^7.0.3" + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/process": "^6.4|^7.0|^8.0", + "symfony/property-access": "^6.4|^7.0|^8.0", + "symfony/property-info": "^6.4|^7.0|^8.0", + "symfony/serializer": "^6.4.3|^7.0.3|^8.0" }, "type": "library", "autoload": { @@ -4959,7 +5015,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v7.3.4" + "source": "https://github.com/symfony/mime/tree/v7.4.0" }, "funding": [ { @@ -4979,7 +5035,7 @@ "type": "tidelift" } ], - "time": "2025-09-16T08:38:17+00:00" + "time": "2025-11-16T10:14:42+00:00" }, { "name": "symfony/polyfill-ctype", @@ -5816,22 +5872,23 @@ }, { "name": "symfony/string", - "version": "v7.3.4", + "version": "v7.4.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "f96476035142921000338bad71e5247fbc138872" + "reference": "d50e862cb0a0e0886f73ca1f31b865efbb795003" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/f96476035142921000338bad71e5247fbc138872", - "reference": "f96476035142921000338bad71e5247fbc138872", + "url": "https://api.github.com/repos/symfony/string/zipball/d50e862cb0a0e0886f73ca1f31b865efbb795003", + "reference": "d50e862cb0a0e0886f73ca1f31b865efbb795003", "shasum": "" }, "require": { "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-grapheme": "~1.33", "symfony/polyfill-intl-normalizer": "~1.0", "symfony/polyfill-mbstring": "~1.0" }, @@ -5839,11 +5896,11 @@ "symfony/translation-contracts": "<2.5" }, "require-dev": { - "symfony/emoji": "^7.1", - "symfony/http-client": "^6.4|^7.0", - "symfony/intl": "^6.4|^7.0", + "symfony/emoji": "^7.1|^8.0", + "symfony/http-client": "^6.4|^7.0|^8.0", + "symfony/intl": "^6.4|^7.0|^8.0", "symfony/translation-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^6.4|^7.0" + "symfony/var-exporter": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { @@ -5882,7 +5939,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.3.4" + "source": "https://github.com/symfony/string/tree/v7.4.0" }, "funding": [ { @@ -5902,27 +5959,27 @@ "type": "tidelift" } ], - "time": "2025-09-11T14:36:48+00:00" + "time": "2025-11-27T13:27:24+00:00" }, { "name": "symfony/translation", - "version": "v7.3.4", + "version": "v7.4.0", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "ec25870502d0c7072d086e8ffba1420c85965174" + "reference": "2d01ca0da3f092f91eeedb46f24aa30d2fca8f68" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/ec25870502d0c7072d086e8ffba1420c85965174", - "reference": "ec25870502d0c7072d086e8ffba1420c85965174", + "url": "https://api.github.com/repos/symfony/translation/zipball/2d01ca0da3f092f91eeedb46f24aa30d2fca8f68", + "reference": "2d01ca0da3f092f91eeedb46f24aa30d2fca8f68", "shasum": "" }, "require": { "php": ">=8.2", "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.0", - "symfony/translation-contracts": "^2.5|^3.0" + "symfony/translation-contracts": "^2.5.3|^3.3" }, "conflict": { "nikic/php-parser": "<5.0", @@ -5941,17 +5998,17 @@ "require-dev": { "nikic/php-parser": "^5.0", "psr/log": "^1|^2|^3", - "symfony/config": "^6.4|^7.0", - "symfony/console": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/finder": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/console": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/finder": "^6.4|^7.0|^8.0", "symfony/http-client-contracts": "^2.5|^3.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/intl": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0|^8.0", + "symfony/intl": "^6.4|^7.0|^8.0", "symfony/polyfill-intl-icu": "^1.21", - "symfony/routing": "^6.4|^7.0", + "symfony/routing": "^6.4|^7.0|^8.0", "symfony/service-contracts": "^2.5|^3", - "symfony/yaml": "^6.4|^7.0" + "symfony/yaml": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { @@ -5982,7 +6039,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v7.3.4" + "source": "https://github.com/symfony/translation/tree/v7.4.0" }, "funding": [ { @@ -6002,7 +6059,7 @@ "type": "tidelift" } ], - "time": "2025-09-07T11:39:36+00:00" + "time": "2025-11-27T13:27:24+00:00" }, { "name": "symfony/translation-contracts", @@ -6088,16 +6145,16 @@ }, { "name": "symfony/var-dumper", - "version": "v7.3.5", + "version": "v7.4.0", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "476c4ae17f43a9a36650c69879dcf5b1e6ae724d" + "reference": "41fd6c4ae28c38b294b42af6db61446594a0dece" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/476c4ae17f43a9a36650c69879dcf5b1e6ae724d", - "reference": "476c4ae17f43a9a36650c69879dcf5b1e6ae724d", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/41fd6c4ae28c38b294b42af6db61446594a0dece", + "reference": "41fd6c4ae28c38b294b42af6db61446594a0dece", "shasum": "" }, "require": { @@ -6109,10 +6166,10 @@ "symfony/console": "<6.4" }, "require-dev": { - "symfony/console": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0", - "symfony/uid": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0|^8.0", + "symfony/http-kernel": "^6.4|^7.0|^8.0", + "symfony/process": "^6.4|^7.0|^8.0", + "symfony/uid": "^6.4|^7.0|^8.0", "twig/twig": "^3.12" }, "bin": [ @@ -6151,7 +6208,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.3.5" + "source": "https://github.com/symfony/var-dumper/tree/v7.4.0" }, "funding": [ { @@ -6171,20 +6228,20 @@ "type": "tidelift" } ], - "time": "2025-09-27T09:00:46+00:00" + "time": "2025-10-27T20:36:44+00:00" }, { "name": "symfony/var-exporter", - "version": "v7.3.4", + "version": "v7.4.0", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "0f020b544a30a7fe8ba972e53ee48a74c0bc87f4" + "reference": "03a60f169c79a28513a78c967316fbc8bf17816f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/0f020b544a30a7fe8ba972e53ee48a74c0bc87f4", - "reference": "0f020b544a30a7fe8ba972e53ee48a74c0bc87f4", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/03a60f169c79a28513a78c967316fbc8bf17816f", + "reference": "03a60f169c79a28513a78c967316fbc8bf17816f", "shasum": "" }, "require": { @@ -6192,9 +6249,9 @@ "symfony/deprecation-contracts": "^2.5|^3" }, "require-dev": { - "symfony/property-access": "^6.4|^7.0", - "symfony/serializer": "^6.4|^7.0", - "symfony/var-dumper": "^6.4|^7.0" + "symfony/property-access": "^6.4|^7.0|^8.0", + "symfony/serializer": "^6.4|^7.0|^8.0", + "symfony/var-dumper": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { @@ -6232,7 +6289,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v7.3.4" + "source": "https://github.com/symfony/var-exporter/tree/v7.4.0" }, "funding": [ { @@ -6252,7 +6309,7 @@ "type": "tidelift" } ], - "time": "2025-09-11T10:12:26+00:00" + "time": "2025-09-11T10:15:23+00:00" }, { "name": "topthink/think-container", @@ -6587,22 +6644,22 @@ }, { "name": "webman/console", - "version": "v2.1.9", + "version": "v2.1.10", "source": { "type": "git", "url": "https://github.com/webman-php/console.git", - "reference": "09c995bf3d9a136c7c471b6db837a1fd56b7d206" + "reference": "6b24bb77d04588c7c3b235087073e69ddfdaa773" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webman-php/console/zipball/09c995bf3d9a136c7c471b6db837a1fd56b7d206", - "reference": "09c995bf3d9a136c7c471b6db837a1fd56b7d206", + "url": "https://api.github.com/repos/webman-php/console/zipball/6b24bb77d04588c7c3b235087073e69ddfdaa773", + "reference": "6b24bb77d04588c7c3b235087073e69ddfdaa773", "shasum": "" }, "require": { "doctrine/inflector": "^2.0", "php": ">=8.1", - "symfony/console": ">=6.0" + "symfony/console": "^6.0 || ^7.0" }, "require-dev": { "workerman/webman": "^2.1" @@ -6637,20 +6694,20 @@ "source": "https://github.com/webman-php/console", "wiki": "http://www.workerman.net/doc/webman" }, - "time": "2025-10-14T09:11:21+00:00" + "time": "2025-12-08T08:23:12+00:00" }, { "name": "webman/database", - "version": "v2.1.6", + "version": "v2.1.7", "source": { "type": "git", "url": "https://github.com/webman-php/database.git", - "reference": "943c5a0f92d8959d9160c2ee3925112b15c308c8" + "reference": "81a8a834cc8db5a5dbb46fe0073a9d5ac73848f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webman-php/database/zipball/943c5a0f92d8959d9160c2ee3925112b15c308c8", - "reference": "943c5a0f92d8959d9160c2ee3925112b15c308c8", + "url": "https://api.github.com/repos/webman-php/database/zipball/81a8a834cc8db5a5dbb46fe0073a9d5ac73848f6", + "reference": "81a8a834cc8db5a5dbb46fe0073a9d5ac73848f6", "shasum": "" }, "require": { @@ -6673,9 +6730,9 @@ "description": "Webman database", "support": { "issues": "https://github.com/webman-php/database/issues", - "source": "https://github.com/webman-php/database/tree/v2.1.6" + "source": "https://github.com/webman-php/database/tree/v2.1.7" }, - "time": "2025-04-04T13:23:25+00:00" + "time": "2025-11-27T08:09:25+00:00" }, { "name": "webman/gateway-worker", @@ -6710,6 +6767,40 @@ }, "time": "2024-04-30T01:05:42+00:00" }, + { + "name": "webman/log", + "version": "v2.1.3", + "source": { + "type": "git", + "url": "https://github.com/webman-php/log.git", + "reference": "14e3f3e64e87783952417a68cf5205c1293aba69" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webman-php/log/zipball/14e3f3e64e87783952417a68cf5205c1293aba69", + "reference": "14e3f3e64e87783952417a68cf5205c1293aba69", + "shasum": "" + }, + "require": { + "workerman/webman-framework": "^2.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Webman\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Webman plugin webman/log", + "support": { + "issues": "https://github.com/webman-php/log/issues", + "source": "https://github.com/webman-php/log/tree/v2.1.3" + }, + "time": "2025-02-26T11:43:36+00:00" + }, { "name": "webman/redis", "version": "v2.1.3", @@ -6748,16 +6839,16 @@ }, { "name": "webman/redis-queue", - "version": "v2.1.0", + "version": "v2.1.1", "source": { "type": "git", "url": "https://github.com/webman-php/redis-queue.git", - "reference": "12e1c9915ec64c91c0c9c255606bd0c7de27334c" + "reference": "ff4791e21f3c324a47e21da7b6f2dae5a7311dcb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webman-php/redis-queue/zipball/12e1c9915ec64c91c0c9c255606bd0c7de27334c", - "reference": "12e1c9915ec64c91c0c9c255606bd0c7de27334c", + "url": "https://api.github.com/repos/webman-php/redis-queue/zipball/ff4791e21f3c324a47e21da7b6f2dae5a7311dcb", + "reference": "ff4791e21f3c324a47e21da7b6f2dae5a7311dcb", "shasum": "" }, "require": { @@ -6776,9 +6867,9 @@ "description": "Redis message queue plugin for webman.", "support": { "issues": "https://github.com/webman-php/redis-queue/issues", - "source": "https://github.com/webman-php/redis-queue/tree/v2.1.0" + "source": "https://github.com/webman-php/redis-queue/tree/v2.1.1" }, - "time": "2025-01-24T12:56:01+00:00" + "time": "2025-11-14T07:12:52+00:00" }, { "name": "workerman/coroutine", @@ -7135,28 +7226,31 @@ "type": "patreon" } ], - "time": "2025-06-12T13:34:04+00:00" + "time": "2025-11-12T01:36:20+00:00" }, { "name": "zoujingli/ip2region", - "version": "v3.0.0", + "version": "v3.0.8", "source": { "type": "git", "url": "https://github.com/zoujingli/ip2region.git", - "reference": "fd31d7a023f28f4e2f3e63f46f1fd51f8b2672f6" + "reference": "4ab4283f4b4ea4222da6cb97fbf7f7167f1ebb53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zoujingli/ip2region/zipball/fd31d7a023f28f4e2f3e63f46f1fd51f8b2672f6", - "reference": "fd31d7a023f28f4e2f3e63f46f1fd51f8b2672f6", + "url": "https://api.github.com/repos/zoujingli/ip2region/zipball/4ab4283f4b4ea4222da6cb97fbf7f7167f1ebb53", + "reference": "4ab4283f4b4ea4222da6cb97fbf7f7167f1ebb53", "shasum": "" }, "require": { - "php": ">=5.4" + "php": ">=7.1.0" }, "suggest": { "ext-opcache": "启用 OPcache 以获得更好的性能" }, + "bin": [ + "bin/ip2down" + ], "type": "library", "extra": { "branch-alias": { @@ -7165,10 +7259,13 @@ }, "autoload": { "files": [ - "ip2region.php" + "src/common.php" ], + "psr-4": { + "ip2region\\": "src/ip2region/" + }, "classmap": [ - "src/" + "src/Ip2Region.php" ] }, "notification-url": "https://packagist.org/downloads/", @@ -7182,30 +7279,28 @@ "homepage": "https://thinkadmin.top" } ], - "description": "Ip2Region v3.0 for PHP - 企业级 IP 地理位置查询库,支持 IPv4/IPv6,分片文件管理,智能缓存,零依赖", + "description": "ip2region v3.0 for PHP - 企业级 IP 地理位置查询库,支持 IPv4 和 IPv6,多种缓存策略,零依赖,开箱即用", "homepage": "https://github.com/zoujingli/Ip2Region", "keywords": [ "IP", - "IP定位", "Ip2Region", - "geoip", + "composer", "geolocation", "ipv4", "ipv6", "location", + "php", "企业级", - "分片数据库", - "压缩", - "地理位置", - "地理位置查询", - "缓存", + "智能加载", + "缓存策略", + "零依赖", "高性能" ], "support": { "issues": "https://github.com/zoujingli/ip2region/issues", - "source": "https://github.com/zoujingli/ip2region/tree/v3.0.0" + "source": "https://github.com/zoujingli/ip2region/tree/v3.0.8" }, - "time": "2025-09-15T12:27:22+00:00" + "time": "2025-11-20T11:02:33+00:00" } ], "packages-dev": [], diff --git a/config/plugin/webman/log/app.php b/config/plugin/webman/log/app.php new file mode 100644 index 0000000..6217553 --- /dev/null +++ b/config/plugin/webman/log/app.php @@ -0,0 +1,19 @@ + true, + 'exception' => [ + // 是否记录异常到日志 + 'enable' => true, + // 不会记录到日志的异常类 + 'dontReport' => [ + support\exception\BusinessException::class + ] + ], + 'dontReport' => [ + 'app' => [], + 'controller' => [], + 'action' => [], + 'path' => [] + ], + 'channel' => 'default' // 日志通道(在config/log.php里配置,默认是default) +]; diff --git a/config/plugin/webman/log/middleware.php b/config/plugin/webman/log/middleware.php new file mode 100644 index 0000000..7c7b0a9 --- /dev/null +++ b/config/plugin/webman/log/middleware.php @@ -0,0 +1,21 @@ + + * @copyright walkor + * @link http://www.workerman.net/ + * @license http://www.opensource.org/licenses/mit-license.php MIT License + */ + +use Webman\Log\Middleware; + +return [ + '@' => [ + Middleware::class + ] +];