From 53700550080fd837308dad254e3822b259647b4e Mon Sep 17 00:00:00 2001 From: mzl Date: Mon, 15 Dec 2025 02:22:19 +0000 Subject: [PATCH] inquiry --- app/command/AssignInquiryCommand.php | 145 +++ app/command/FbLeadToInquiryCommand.php | 164 +++ app/command/TbCommand.php | 256 ++++ app/controller/IndexController.php | 5 + app/controller/TransmitController.php | 35 + app/inquery/controller/InqueryController.php | 61 + app/inquery/utils/FbLeadHeaderMapper.php | 154 +++ app/inquery/utils/PhoneCountryHelper.php | 58 + app/inquery/utils/RoundRobinAssigner.php | 46 + app/utils/Cf7InquiryClient.php | 93 ++ composer.json | 12 +- composer.lock | 1101 ++++++++++++++++- config/database.php | 12 +- config/plugin/webman/console/app.php | 24 + config/plugin/webman/redis-queue/app.php | 4 + config/plugin/webman/redis-queue/command.php | 7 + config/plugin/webman/redis-queue/log.php | 32 + config/plugin/webman/redis-queue/process.php | 11 + config/plugin/webman/redis-queue/redis.php | 22 + config/redis.php | 29 + config/route.php | 4 +- .../BYD tang_Leads_2025-12-04_2025-12-09.xlsx | Bin 0 -> 12277 bytes ...lla Cross_Leads_2025-12-04_2025-12-09.xlsx | Bin 0 -> 13235 bytes .../ROX 01_Leads_2025-12-04_2025-12-09.xlsx | Bin 0 -> 15736 bytes ...yota RAV4_Leads_2025-12-04_2025-12-09.xlsx | Bin 0 -> 16107 bytes ...NISSAN Z9_Leads_2025-12-04_2025-12-09.xlsx | Bin 0 -> 14161 bytes ...song plus_Leads_2025-12-04_2025-12-09.xlsx | Bin 0 -> 12846 bytes ...jetour t2_Leads_2025-12-04_2025-12-09.xlsx | Bin 0 -> 17480 bytes ...leopard 5_Leads_2025-12-04_2025-12-09.xlsx | Bin 0 -> 11468 bytes webman | 71 ++ 30 files changed, 2299 insertions(+), 47 deletions(-) create mode 100644 app/command/AssignInquiryCommand.php create mode 100644 app/command/FbLeadToInquiryCommand.php create mode 100644 app/command/TbCommand.php create mode 100644 app/controller/TransmitController.php create mode 100644 app/inquery/controller/InqueryController.php create mode 100644 app/inquery/utils/FbLeadHeaderMapper.php create mode 100644 app/inquery/utils/PhoneCountryHelper.php create mode 100644 app/inquery/utils/RoundRobinAssigner.php create mode 100644 app/utils/Cf7InquiryClient.php create mode 100644 config/plugin/webman/console/app.php create mode 100644 config/plugin/webman/redis-queue/app.php create mode 100644 config/plugin/webman/redis-queue/command.php create mode 100644 config/plugin/webman/redis-queue/log.php create mode 100644 config/plugin/webman/redis-queue/process.php create mode 100644 config/plugin/webman/redis-queue/redis.php create mode 100644 config/redis.php create mode 100644 public/excel/BYD tang_Leads_2025-12-04_2025-12-09.xlsx create mode 100644 public/excel/Corolla Cross_Leads_2025-12-04_2025-12-09.xlsx create mode 100644 public/excel/ROX 01_Leads_2025-12-04_2025-12-09.xlsx create mode 100644 public/excel/Toyota RAV4_Leads_2025-12-04_2025-12-09.xlsx create mode 100644 public/excel/ZHENGZHOU NISSAN Z9_Leads_2025-12-04_2025-12-09.xlsx create mode 100644 public/excel/byd song plus_Leads_2025-12-04_2025-12-09.xlsx create mode 100644 public/excel/jetour t2_Leads_2025-12-04_2025-12-09.xlsx create mode 100644 public/excel/leopard 5_Leads_2025-12-04_2025-12-09.xlsx create mode 100755 webman diff --git a/app/command/AssignInquiryCommand.php b/app/command/AssignInquiryCommand.php new file mode 100644 index 0000000..b33b482 --- /dev/null +++ b/app/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/command/FbLeadToInquiryCommand.php b/app/command/FbLeadToInquiryCommand.php new file mode 100644 index 0000000..36ec869 --- /dev/null +++ b/app/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/command/TbCommand.php b/app/command/TbCommand.php new file mode 100644 index 0000000..9f505a4 --- /dev/null +++ b/app/command/TbCommand.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/controller/IndexController.php b/app/controller/IndexController.php index c6489a3..1a5d257 100644 --- a/app/controller/IndexController.php +++ b/app/controller/IndexController.php @@ -9,6 +9,11 @@ use support\Log; class IndexController { + public function index() + { + return 22; + } + public function form(Request $request, int $id) { try { diff --git a/app/controller/TransmitController.php b/app/controller/TransmitController.php new file mode 100644 index 0000000..e96e283 --- /dev/null +++ b/app/controller/TransmitController.php @@ -0,0 +1,35 @@ +fetchForms(); + + $result = $client->fetchEntries(263, 0, 10); + + return json($result); + } catch (\Throwable $th) { + Log::info('Data:'.date('Y-m-d H:i:s').':'.$th->getMessage().'|'.$th->getLine().'|'.$th->getFile()); + } + } + +} \ No newline at end of file diff --git a/app/inquery/controller/InqueryController.php b/app/inquery/controller/InqueryController.php new file mode 100644 index 0000000..0ee0b0e --- /dev/null +++ b/app/inquery/controller/InqueryController.php @@ -0,0 +1,61 @@ +getActiveSheet(); + $rows = $sheet->toArray(null, true, true, true); + + if (empty($rows)) { + throw new BusinessException('Excel 内容为空'); + } + + // 取第一行表头 + $headerRow = array_shift($rows); + + // 实例化映射器 + $mapper = new FbLeadHeaderMapper(); + + // ① 如果有未知表头,会在这里抛出异常并终止处理 + $colToField = $mapper->buildColumnFieldMap($headerRow); + + // ② 开始处理数据行 + $insertData = []; + $now = time(); + + foreach ($rows as $row) { + $item = []; + + foreach ($colToField as $colIndex => $field) { + $item[$field] = $row[$colIndex] ?? null; + } + + // 补充你需要的其他字段 + $item['source_file'] = basename($filePath); + $item['created_at'] = $now; + $item['updated_at'] = $now; + + $insertData[] = $item; + } + + // ③ 批量入库(根据你的实际需求做去重等逻辑) + if ($insertData) { + Db::table('fb_leads')->insert($insertData); + } + } + +} \ No newline at end of file diff --git a/app/inquery/utils/FbLeadHeaderMapper.php b/app/inquery/utils/FbLeadHeaderMapper.php new file mode 100644 index 0000000..59b1cb5 --- /dev/null +++ b/app/inquery/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/inquery/utils/PhoneCountryHelper.php b/app/inquery/utils/PhoneCountryHelper.php new file mode 100644 index 0000000..78ec4ab --- /dev/null +++ b/app/inquery/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/inquery/utils/RoundRobinAssigner.php b/app/inquery/utils/RoundRobinAssigner.php new file mode 100644 index 0000000..5063884 --- /dev/null +++ b/app/inquery/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]; + } +} diff --git a/app/utils/Cf7InquiryClient.php b/app/utils/Cf7InquiryClient.php new file mode 100644 index 0000000..adf264b --- /dev/null +++ b/app/utils/Cf7InquiryClient.php @@ -0,0 +1,93 @@ +baseUri = rtrim($baseUri, '/'); + + $config = [ + 'base_uri' => $this->baseUri, + 'auth' => [$username, $password], + 'timeout' => $options['timeout'] ?? 10, + 'verify' => $options['verify'] ?? false, // 正式环境建议改成 true + ]; + + $this->client = new Client($config); + } + + /** + * 获取当前站点的 CF7 表单列表(从 Advanced CF7 DB 推断) + * 对应插件里的 /acf7db/v1/forms + * + * @return array + * @throws GuzzleException + */ + public function fetchForms(): array + { + $response = $this->client->get('/wp-json/acf7db/v1/forms'); + $body = (string)$response->getBody(); + + return json_decode($body, true) ?: []; + } + + /** + * 获取 Advanced CF7 DB 询盘列表(存量 + 增量通用) + * + * @param int $cf7Id 表单 ID(可选,为 0 时表示所有表单) + * @param int $lastId 上次同步到的最大 submit_id + * @param int $perPage 每次拉取数量 + * @param string|null $from 起始时间(可选,Y-m-d H:i:s) + * @param string|null $to 结束时间(可选) + * + * @return array ['data' => [...], 'meta' => [...]] + * @throws GuzzleException + */ + public function fetchEntries( + int $cf7Id = 0, + int $lastId = 0, + int $perPage = 200, + ?string $from = null, + ?string $to = null + ): array { + $query = [ + 'last_id' => $lastId, + 'per_page' => $perPage, + ]; + + if ($cf7Id > 0) { + $query['cf7_id'] = $cf7Id; + } + if ($from) { + $query['from'] = $from; + } + if ($to) { + $query['to'] = $to; + } + + $response = $this->client->get('/wp-json/acf7db/v1/entries', [ + 'query' => $query, + ]); + + $body = (string)$response->getBody(); + return json_decode($body, true) ?: ['data' => [], 'meta' => []]; + } +} diff --git a/composer.json b/composer.json index 34464e3..b51dd8c 100644 --- a/composer.json +++ b/composer.json @@ -29,11 +29,15 @@ "monolog/monolog": "^2.0", "vlucas/phpdotenv": "^5.6", "webman/database": "^2.1", - "illuminate/pagination": "^12.37", - "illuminate/events": "^12.37", - "symfony/var-dumper": "^7.3", + "illuminate/pagination": "^12.42", + "illuminate/events": "^12.42", + "symfony/var-dumper": "^7.4", "phpmailer/phpmailer": "^7.0", - "zoujingli/ip2region": "^3.0" + "zoujingli/ip2region": "^3.0", + "phpoffice/phpspreadsheet": "^5.3", + "webman/console": "^2.1", + "webman/redis": "^2.1", + "webman/redis-queue": "^2.1" }, "suggest": { "ext-event": "For better performance. " diff --git a/composer.lock b/composer.lock index d54d545..4d5f7c3 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "48c77686c3f22f2ca6b7174d010a7656", + "content-hash": "bacff953706f64356bf4c93c5e0f7dad", "packages": [ { "name": "brick/math", @@ -135,6 +135,85 @@ ], "time": "2024-02-09T16:56:22+00:00" }, + { + "name": "composer/pcre", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<1.11.10" + }, + "require-dev": { + "phpstan/phpstan": "^1.12 || ^2", + "phpstan/phpstan-strict-rules": "^1 || ^2", + "phpunit/phpunit": "^8 || ^9" + }, + "type": "library", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.3.2" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-11-12T16:29:46+00:00" + }, { "name": "doctrine/inflector", "version": "2.1.0", @@ -771,7 +850,7 @@ }, { "name": "illuminate/bus", - "version": "v12.41.1", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/bus.git", @@ -824,16 +903,16 @@ }, { "name": "illuminate/collections", - "version": "v12.41.1", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/collections.git", - "reference": "1cf6115f711ff775fcce547dee82d59cac33fedb" + "reference": "16657effa6a5a4e728f9aeb3e38fb4fa9ba70e7d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/collections/zipball/1cf6115f711ff775fcce547dee82d59cac33fedb", - "reference": "1cf6115f711ff775fcce547dee82d59cac33fedb", + "url": "https://api.github.com/repos/illuminate/collections/zipball/16657effa6a5a4e728f9aeb3e38fb4fa9ba70e7d", + "reference": "16657effa6a5a4e728f9aeb3e38fb4fa9ba70e7d", "shasum": "" }, "require": { @@ -879,11 +958,11 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-11-29T13:55:43+00:00" + "time": "2025-12-06T18:08:25+00:00" }, { "name": "illuminate/conditionable", - "version": "v12.41.1", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/conditionable.git", @@ -929,20 +1008,21 @@ }, { "name": "illuminate/container", - "version": "v12.41.1", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/container.git", - "reference": "0489bc396de1537537750babec3a03ee7b753d1f" + "reference": "326667a4c813e3ad5a645969a7e3f5c10d159de2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/container/zipball/0489bc396de1537537750babec3a03ee7b753d1f", - "reference": "0489bc396de1537537750babec3a03ee7b753d1f", + "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", @@ -986,11 +1066,11 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-11-28T18:51:53+00:00" + "time": "2025-12-08T22:34:25+00:00" }, { "name": "illuminate/contracts", - "version": "v12.41.1", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/contracts.git", @@ -1038,16 +1118,16 @@ }, { "name": "illuminate/database", - "version": "v12.41.1", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/database.git", - "reference": "199e9200a08c1841a31932e0a36a4094de84b72d" + "reference": "b44f021fee7b48289312e22fd6e4d580374a86ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/database/zipball/199e9200a08c1841a31932e0a36a4094de84b72d", - "reference": "199e9200a08c1841a31932e0a36a4094de84b72d", + "url": "https://api.github.com/repos/illuminate/database/zipball/b44f021fee7b48289312e22fd6e4d580374a86ac", + "reference": "b44f021fee7b48289312e22fd6e4d580374a86ac", "shasum": "" }, "require": { @@ -1105,11 +1185,11 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-12-01T15:01:30+00:00" + "time": "2025-12-06T18:08:25+00:00" }, { "name": "illuminate/events", - "version": "v12.41.1", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/events.git", @@ -1164,7 +1244,7 @@ }, { "name": "illuminate/filesystem", - "version": "v12.41.1", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/filesystem.git", @@ -1231,16 +1311,16 @@ }, { "name": "illuminate/http", - "version": "v12.41.1", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/http.git", - "reference": "cdabd462fa50ab057da4807b980c861326c5a345" + "reference": "b7997f2faffb3c31f2a0fa079428ff6bfcce8907" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/http/zipball/cdabd462fa50ab057da4807b980c861326c5a345", - "reference": "cdabd462fa50ab057da4807b980c861326c5a345", + "url": "https://api.github.com/repos/illuminate/http/zipball/b7997f2faffb3c31f2a0fa079428ff6bfcce8907", + "reference": "b7997f2faffb3c31f2a0fa079428ff6bfcce8907", "shasum": "" }, "require": { @@ -1289,11 +1369,11 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-11-28T18:00:52+00:00" + "time": "2025-12-09T15:25:50+00:00" }, { "name": "illuminate/macroable", - "version": "v12.41.1", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/macroable.git", @@ -1339,7 +1419,7 @@ }, { "name": "illuminate/pagination", - "version": "v12.41.1", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/pagination.git", @@ -1389,7 +1469,7 @@ }, { "name": "illuminate/pipeline", - "version": "v12.41.1", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/pipeline.git", @@ -1439,9 +1519,114 @@ }, "time": "2025-08-20T13:36:50+00:00" }, + { + "name": "illuminate/redis", + "version": "v12.42.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/redis.git", + "reference": "8dc6682638100db9feceaac3db206de752dd0f9a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/redis/zipball/8dc6682638100db9feceaac3db206de752dd0f9a", + "reference": "8dc6682638100db9feceaac3db206de752dd0f9a", + "shasum": "" + }, + "require": { + "illuminate/collections": "^12.0", + "illuminate/contracts": "^12.0", + "illuminate/macroable": "^12.0", + "illuminate/support": "^12.0", + "php": "^8.2" + }, + "suggest": { + "ext-redis": "Required to use the phpredis connector (^4.0|^5.0|^6.0).", + "predis/predis": "Required to use the predis connector (^2.3|^3.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "12.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Redis\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Redis package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "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.41.1", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/session.git", @@ -1498,16 +1683,16 @@ }, { "name": "illuminate/support", - "version": "v12.41.1", + "version": "v12.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/support.git", - "reference": "c65715d8a41863ee3f2e22dc796b75c62143fca2" + "reference": "d35411be5657e0b5560a5885f3c9140e4cbe0be5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/support/zipball/c65715d8a41863ee3f2e22dc796b75c62143fca2", - "reference": "c65715d8a41863ee3f2e22dc796b75c62143fca2", + "url": "https://api.github.com/repos/illuminate/support/zipball/d35411be5657e0b5560a5885f3c9140e4cbe0be5", + "reference": "d35411be5657e0b5560a5885f3c9140e4cbe0be5", "shasum": "" }, "require": { @@ -1519,6 +1704,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", @@ -1573,7 +1759,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-12-03T01:01:36+00:00" + "time": "2025-12-09T15:26:52+00:00" }, { "name": "laravel/serializable-closure", @@ -1636,6 +1822,191 @@ }, "time": "2025-11-21T20:52:36+00:00" }, + { + "name": "maennchen/zipstream-php", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/maennchen/ZipStream-PHP.git", + "reference": "9712d8fa4cdf9240380b01eb4be55ad8dcf71416" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/9712d8fa4cdf9240380b01eb4be55ad8dcf71416", + "reference": "9712d8fa4cdf9240380b01eb4be55ad8dcf71416", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "ext-zlib": "*", + "php-64bit": "^8.3" + }, + "require-dev": { + "brianium/paratest": "^7.7", + "ext-zip": "*", + "friendsofphp/php-cs-fixer": "^3.16", + "guzzlehttp/guzzle": "^7.5", + "mikey179/vfsstream": "^1.6", + "php-coveralls/php-coveralls": "^2.5", + "phpunit/phpunit": "^12.0", + "vimeo/psalm": "^6.0" + }, + "suggest": { + "guzzlehttp/psr7": "^2.4", + "psr/http-message": "^2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "ZipStream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paul Duncan", + "email": "pabs@pablotron.org" + }, + { + "name": "Jonatan Männchen", + "email": "jonatan@maennchen.ch" + }, + { + "name": "Jesse Donat", + "email": "donatj@gmail.com" + }, + { + "name": "András Kolesár", + "email": "kolesar@kolesar.hu" + } + ], + "description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.", + "keywords": [ + "stream", + "zip" + ], + "support": { + "issues": "https://github.com/maennchen/ZipStream-PHP/issues", + "source": "https://github.com/maennchen/ZipStream-PHP/tree/3.2.0" + }, + "funding": [ + { + "url": "https://github.com/maennchen", + "type": "github" + } + ], + "time": "2025-07-17T11:15:13+00:00" + }, + { + "name": "markbaker/complex", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/MarkBaker/PHPComplex.git", + "reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/95c56caa1cf5c766ad6d65b6344b807c1e8405b9", + "reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "dev-master", + "phpcompatibility/php-compatibility": "^9.3", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", + "squizlabs/php_codesniffer": "^3.7" + }, + "type": "library", + "autoload": { + "psr-4": { + "Complex\\": "classes/src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Baker", + "email": "mark@lange.demon.co.uk" + } + ], + "description": "PHP Class for working with complex numbers", + "homepage": "https://github.com/MarkBaker/PHPComplex", + "keywords": [ + "complex", + "mathematics" + ], + "support": { + "issues": "https://github.com/MarkBaker/PHPComplex/issues", + "source": "https://github.com/MarkBaker/PHPComplex/tree/3.0.2" + }, + "time": "2022-12-06T16:21:08+00:00" + }, + { + "name": "markbaker/matrix", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/MarkBaker/PHPMatrix.git", + "reference": "728434227fe21be27ff6d86621a1b13107a2562c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/728434227fe21be27ff6d86621a1b13107a2562c", + "reference": "728434227fe21be27ff6d86621a1b13107a2562c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "dev-master", + "phpcompatibility/php-compatibility": "^9.3", + "phpdocumentor/phpdocumentor": "2.*", + "phploc/phploc": "^4.0", + "phpmd/phpmd": "2.*", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", + "sebastian/phpcpd": "^4.0", + "squizlabs/php_codesniffer": "^3.7" + }, + "type": "library", + "autoload": { + "psr-4": { + "Matrix\\": "classes/src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Baker", + "email": "mark@demon-angel.eu" + } + ], + "description": "PHP Class for working with matrices", + "homepage": "https://github.com/MarkBaker/PHPMatrix", + "keywords": [ + "mathematics", + "matrix", + "vector" + ], + "support": { + "issues": "https://github.com/MarkBaker/PHPMatrix/issues", + "source": "https://github.com/MarkBaker/PHPMatrix/tree/3.0.1" + }, + "time": "2022-12-02T22:17:43+00:00" + }, { "name": "monolog/monolog", "version": "2.10.0", @@ -1975,6 +2346,112 @@ ], "time": "2025-11-25T07:18:09+00:00" }, + { + "name": "phpoffice/phpspreadsheet", + "version": "5.3.0", + "source": { + "type": "git", + "url": "https://github.com/PHPOffice/PhpSpreadsheet.git", + "reference": "4d597c1aacdde1805a33c525b9758113ea0d90df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/4d597c1aacdde1805a33c525b9758113ea0d90df", + "reference": "4d597c1aacdde1805a33c525b9758113ea0d90df", + "shasum": "" + }, + "require": { + "composer/pcre": "^1||^2||^3", + "ext-ctype": "*", + "ext-dom": "*", + "ext-fileinfo": "*", + "ext-gd": "*", + "ext-iconv": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-simplexml": "*", + "ext-xml": "*", + "ext-xmlreader": "*", + "ext-xmlwriter": "*", + "ext-zip": "*", + "ext-zlib": "*", + "maennchen/zipstream-php": "^2.1 || ^3.0", + "markbaker/complex": "^3.0", + "markbaker/matrix": "^3.0", + "php": "^8.1", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0", + "psr/simple-cache": "^1.0 || ^2.0 || ^3.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "dev-main", + "dompdf/dompdf": "^2.0 || ^3.0", + "friendsofphp/php-cs-fixer": "^3.2", + "mitoteam/jpgraph": "^10.5", + "mpdf/mpdf": "^8.1.1", + "phpcompatibility/php-compatibility": "^9.3", + "phpstan/phpstan": "^1.1 || ^2.0", + "phpstan/phpstan-deprecation-rules": "^1.0 || ^2.0", + "phpstan/phpstan-phpunit": "^1.0 || ^2.0", + "phpunit/phpunit": "^10.5", + "squizlabs/php_codesniffer": "^3.7", + "tecnickcom/tcpdf": "^6.5" + }, + "suggest": { + "dompdf/dompdf": "Option for rendering PDF with PDF Writer", + "ext-intl": "PHP Internationalization Functions, required for NumberFormat Wizard", + "mitoteam/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers", + "mpdf/mpdf": "Option for rendering PDF with PDF Writer", + "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer" + }, + "type": "library", + "autoload": { + "psr-4": { + "PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Maarten Balliauw", + "homepage": "https://blog.maartenballiauw.be" + }, + { + "name": "Mark Baker", + "homepage": "https://markbakeruk.net" + }, + { + "name": "Franck Lefevre", + "homepage": "https://rootslabs.net" + }, + { + "name": "Erik Tilt" + }, + { + "name": "Adrien Crivelli" + } + ], + "description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine", + "homepage": "https://github.com/PHPOffice/PhpSpreadsheet", + "keywords": [ + "OpenXML", + "excel", + "gnumeric", + "ods", + "php", + "spreadsheet", + "xls", + "xlsx" + ], + "support": { + "issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues", + "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/5.3.0" + }, + "time": "2025-11-24T15:47:10+00:00" + }, { "name": "phpoption/phpoption", "version": "1.9.4", @@ -2584,6 +3061,104 @@ ], "time": "2025-11-12T15:39:26+00:00" }, + { + "name": "symfony/console", + "version": "v7.4.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "6d9f0fbf2ec2e9785880096e3abd0ca0c88b506e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/6d9f0fbf2ec2e9785880096e3abd0ca0c88b506e", + "reference": "6d9f0fbf2ec2e9785880096e3abd0ca0c88b506e", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^7.2|^8.0" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "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": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v7.4.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "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": "2025-12-05T15:23:39+00:00" + }, { "name": "symfony/deprecation-contracts", "version": "v3.6.0", @@ -3335,6 +3910,88 @@ ], "time": "2024-09-09T11:45:10+00:00" }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70", + "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "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": "2025-06-27T09:58:17+00:00" + }, { "name": "symfony/polyfill-intl-idn", "version": "v1.33.0", @@ -3916,6 +4573,184 @@ ], "time": "2025-06-23T16:12:55+00:00" }, + { + "name": "symfony/service-contracts", + "version": "v3.6.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/45112560a3ba2d715666a509a0bc9521d10b6c43", + "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.6.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "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": "2025-07-15T11:30:57+00:00" + }, + { + "name": "symfony/string", + "version": "v7.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "d50e862cb0a0e0886f73ca1f31b865efbb795003" + }, + "dist": { + "type": "zip", + "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.33", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" + }, + "require-dev": { + "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|^8.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v7.4.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "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": "2025-11-27T13:27:24+00:00" + }, { "name": "symfony/translation", "version": "v7.4.0", @@ -4343,6 +5178,60 @@ ], "time": "2024-11-21T01:49:47+00:00" }, + { + "name": "webman/console", + "version": "v2.1.10", + "source": { + "type": "git", + "url": "https://github.com/webman-php/console.git", + "reference": "6b24bb77d04588c7c3b235087073e69ddfdaa773" + }, + "dist": { + "type": "zip", + "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 || ^7.0" + }, + "require-dev": { + "workerman/webman": "^2.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Webman\\Console\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "walkor", + "email": "walkor@workerman.net", + "homepage": "http://www.workerman.net", + "role": "Developer" + } + ], + "description": "Webman console", + "homepage": "http://www.workerman.net", + "keywords": [ + "webman console" + ], + "support": { + "email": "walkor@workerman.net", + "forum": "http://www.workerman.net/questions", + "issues": "https://github.com/webman-php/console/issues", + "source": "https://github.com/webman-php/console", + "wiki": "http://www.workerman.net/doc/webman" + }, + "time": "2025-12-08T08:23:12+00:00" + }, { "name": "webman/database", "version": "v2.1.7", @@ -4381,6 +5270,76 @@ }, "time": "2025-11-27T08:09:25+00:00" }, + { + "name": "webman/redis", + "version": "v2.1.3", + "source": { + "type": "git", + "url": "https://github.com/webman-php/redis.git", + "reference": "559eb1692d39c6fef5cf526223fff728be6c0fb9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webman-php/redis/zipball/559eb1692d39c6fef5cf526223fff728be6c0fb9", + "reference": "559eb1692d39c6fef5cf526223fff728be6c0fb9", + "shasum": "" + }, + "require": { + "illuminate/redis": "^10.0 || ^11.0 || ^12.0", + "workerman/webman-framework": "^2.1 || dev-master" + }, + "type": "library", + "autoload": { + "psr-4": { + "support\\": "src/support", + "Webman\\Redis\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Webman redis", + "support": { + "issues": "https://github.com/webman-php/redis/issues", + "source": "https://github.com/webman-php/redis/tree/v2.1.3" + }, + "time": "2025-03-14T03:52:14+00:00" + }, + { + "name": "webman/redis-queue", + "version": "v2.1.1", + "source": { + "type": "git", + "url": "https://github.com/webman-php/redis-queue.git", + "reference": "ff4791e21f3c324a47e21da7b6f2dae5a7311dcb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webman-php/redis-queue/zipball/ff4791e21f3c324a47e21da7b6f2dae5a7311dcb", + "reference": "ff4791e21f3c324a47e21da7b6f2dae5a7311dcb", + "shasum": "" + }, + "require": { + "ext-redis": "*", + "php": ">=8.1", + "workerman/redis-queue": "^1.2", + "workerman/webman-framework": "^2.1 || dev-master" + }, + "type": "library", + "autoload": { + "psr-4": { + "Webman\\RedisQueue\\": "./src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "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.1" + }, + "time": "2025-11-14T07:12:52+00:00" + }, { "name": "workerman/coroutine", "version": "v1.1.4", @@ -4420,6 +5379,78 @@ }, "time": "2025-10-11T15:09:08+00:00" }, + { + "name": "workerman/redis", + "version": "v2.0.5", + "source": { + "type": "git", + "url": "https://github.com/walkor/redis.git", + "reference": "49627c1809eff1ef7175eb8ee7549234a1d67ec5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/walkor/redis/zipball/49627c1809eff1ef7175eb8ee7549234a1d67ec5", + "reference": "49627c1809eff1ef7175eb8ee7549234a1d67ec5", + "shasum": "" + }, + "require": { + "php": ">=7", + "workerman/workerman": "^4.1.0||^5.0.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Workerman\\Redis\\": "./src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "homepage": "http://www.workerman.net", + "support": { + "issues": "https://github.com/walkor/redis/issues", + "source": "https://github.com/walkor/redis/tree/v2.0.5" + }, + "time": "2025-04-07T01:58:58+00:00" + }, + { + "name": "workerman/redis-queue", + "version": "v1.2.1", + "source": { + "type": "git", + "url": "https://github.com/walkor/redis-queue.git", + "reference": "75dbf7ed2ea228c45dc0df82c0fea35879b715d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/walkor/redis-queue/zipball/75dbf7ed2ea228c45dc0df82c0fea35879b715d0", + "reference": "75dbf7ed2ea228c45dc0df82c0fea35879b715d0", + "shasum": "" + }, + "require": { + "php": ">=7.0", + "workerman/redis": "^1.0||^2.0", + "workerman/workerman": ">=4.0.20" + }, + "type": "library", + "autoload": { + "psr-4": { + "Workerman\\RedisQueue\\": "./src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Message queue system written in PHP based on workerman and backed by Redis.", + "homepage": "http://www.workerman.net", + "support": { + "issues": "https://github.com/walkor/redis-queue/issues", + "source": "https://github.com/walkor/redis-queue/tree/v1.2.1" + }, + "time": "2025-01-02T09:21:45+00:00" + }, { "name": "workerman/webman-framework", "version": "v2.1.4", diff --git a/config/database.php b/config/database.php index e436e95..93308ad 100644 --- a/config/database.php +++ b/config/database.php @@ -4,14 +4,14 @@ return [ 'connections' => [ 'mysql' => [ 'driver' => 'mysql', - 'host' => '127.0.0.1', - 'port' => '3306', - 'database' => 'your_database', - 'username' => 'your_username', - 'password' => 'your_password', + 'host' => getenv('DB_HOST'), + 'port' => getenv('DB_PORT'), + 'database' => getenv('DB_NAME'), + 'username' => getenv('DB_USER'), + 'password' => getenv('DB_PASSWORD'), 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_general_ci', - 'prefix' => '', + 'prefix' => getenv('DB_PREFIX'), 'strict' => true, 'engine' => null, 'options' => [ diff --git a/config/plugin/webman/console/app.php b/config/plugin/webman/console/app.php new file mode 100644 index 0000000..074e986 --- /dev/null +++ b/config/plugin/webman/console/app.php @@ -0,0 +1,24 @@ + true, + + 'build_dir' => BASE_PATH . DIRECTORY_SEPARATOR . 'build', + + 'phar_filename' => 'webman.phar', + + 'bin_filename' => 'webman.bin', + + 'signature_algorithm'=> Phar::SHA256, //set the signature algorithm for a phar and apply it. The signature algorithm must be one of Phar::MD5, Phar::SHA1, Phar::SHA256, Phar::SHA512, or Phar::OPENSSL. + + 'private_key_file' => '', // The file path for certificate or OpenSSL private key file. + + 'exclude_pattern' => '#^(?!.*(composer.json|/.github/|/.idea/|/.git/|/.setting/|/runtime/|/vendor-bin/|/build/|/vendor/webman/admin/))(.*)$#', + + 'exclude_files' => [ + '.env', 'LICENSE', 'composer.json', 'composer.lock', 'start.php', 'webman.phar', 'webman.bin' + ], + + 'custom_ini' => ' +memory_limit = 256M + ', +]; diff --git a/config/plugin/webman/redis-queue/app.php b/config/plugin/webman/redis-queue/app.php new file mode 100644 index 0000000..8f9c426 --- /dev/null +++ b/config/plugin/webman/redis-queue/app.php @@ -0,0 +1,4 @@ + true, +]; \ No newline at end of file diff --git a/config/plugin/webman/redis-queue/command.php b/config/plugin/webman/redis-queue/command.php new file mode 100644 index 0000000..8bfe2a1 --- /dev/null +++ b/config/plugin/webman/redis-queue/command.php @@ -0,0 +1,7 @@ + + * @copyright walkor + * @link http://www.workerman.net/ + * @license http://www.opensource.org/licenses/mit-license.php MIT License + */ + +return [ + 'default' => [ + 'handlers' => [ + [ + 'class' => Monolog\Handler\RotatingFileHandler::class, + 'constructor' => [ + runtime_path() . '/logs/redis-queue/queue.log', + 7, //$maxFiles + Monolog\Logger::DEBUG, + ], + 'formatter' => [ + 'class' => Monolog\Formatter\LineFormatter::class, + 'constructor' => [null, 'Y-m-d H:i:s', true], + ], + ] + ], + ] +]; diff --git a/config/plugin/webman/redis-queue/process.php b/config/plugin/webman/redis-queue/process.php new file mode 100644 index 0000000..c8d4da1 --- /dev/null +++ b/config/plugin/webman/redis-queue/process.php @@ -0,0 +1,11 @@ + [ + 'handler' => Webman\RedisQueue\Process\Consumer::class, + 'count' => 8, // 可以设置多进程同时消费 + 'constructor' => [ + // 消费者类目录 + 'consumer_dir' => app_path() . '/queue/redis' + ] + ] +]; \ No newline at end of file diff --git a/config/plugin/webman/redis-queue/redis.php b/config/plugin/webman/redis-queue/redis.php new file mode 100644 index 0000000..420914d --- /dev/null +++ b/config/plugin/webman/redis-queue/redis.php @@ -0,0 +1,22 @@ + [ +// 'host' => 'redis://127.0.0.1:6379', + 'host' => getenv('REDIS_QUEUE_HOST'), + 'options' => [ + 'auth' => getenv('REDIS_QUEUE_AUTH'), // 密码,字符串类型,可选参数 + 'db' => getenv('REDIS_QUEUE_DB'), // 数据库 + 'prefix' => getenv('REDIS_QUEUE_PREFIX'), // key 前缀 + 'max_attempts' => getenv('REDIS_QUEUE_MAX_ATTEMPTS'), // 消费失败后,重试次数 + 'retry_seconds' => getenv('REDIS_QUEUE_RETRY_SECONDS'), // 重试间隔,单位秒 + ], + // Connection pool, supports only Swoole or Swow drivers. + 'pool' => [ + 'max_connections' => 5, + 'min_connections' => 1, + 'wait_timeout' => 3, + 'idle_timeout' => 60, + 'heartbeat_interval' => 50, + ] + ], +]; diff --git a/config/redis.php b/config/redis.php new file mode 100644 index 0000000..0508ef6 --- /dev/null +++ b/config/redis.php @@ -0,0 +1,29 @@ + + * @copyright walkor + * @link http://www.workerman.net/ + * @license http://www.opensource.org/licenses/mit-license.php MIT License + */ + +return [ + 'default' => [ + 'password' => getenv('REDIS_PASSWORD'), + 'host' => getenv('REDIS_HOST'), + 'port' => getenv('REDIS_PORT'), + 'database' => getenv('REDIS_DATABASE'), + 'pool' => [ + 'max_connections' => 5, + 'min_connections' => 1, + 'wait_timeout' => 3, + 'idle_timeout' => 60, + 'heartbeat_interval' => 50, + ], + ] +]; diff --git a/config/route.php b/config/route.php index cb45b8d..fd6c729 100644 --- a/config/route.php +++ b/config/route.php @@ -16,6 +16,6 @@ use Webman\Route; -Route::any('/form/{id}', [app\controller\IndexController::class, 'form']); - +Route::any('/ts/form', [app\controller\TransmitController::class, 'form']); +Route::any('/iq/form', [app\inquery\controller\InqueryController::class, 'form']); diff --git a/public/excel/BYD tang_Leads_2025-12-04_2025-12-09.xlsx b/public/excel/BYD tang_Leads_2025-12-04_2025-12-09.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..9c6b3b528ff5b79eedb716ae87d647047feb80be GIT binary patch literal 12277 zcma)i1ymhN)-~<~C%9X14eo^CfndRcyIfp@T-@E=-QC^Yg9Hd}L4)gmNoMBF%gi_H z?^Wwc_p#bleY)$^mY0TvLI8U?0^~M?UcUc%z=M7m0QBW;0oHa*@*pux&G|S?8o%0%LvA2G% z?{7Z&)vWUhLN2aoNgVlnXBbzPH{plBd;3`+Z%Z9!56^B%sv@sz;alJIV2v4vN{+;}y-LhOE9ANor zqU}!`jr*#c_qSGO(0@l)it0NyCkS0}5V~mpj;=ny*6;=1xF})i9%dZ>6YuA&tyL;h zV@|1M;IP~)m=u{-35j;gJ}P9%+T{+;!zG@nkbzSHmvay8^IL`aE@~VNj$$EpG8(Wx ze1#%+U^-`rwLipRB6_J6CgvU#_SndBO6p-KCyYw|l#V9!+fyn-wsJ&!YdK>a4G*v( zi!J!=9xZ(eyC;*YPi#-)S6=!eAL+YTx(IrVbqn8T8Jr}oL%i$^Yr6E?OHC6QFr!3SsgYG8 z0h_&EjpIu|RGqm27;!~fwi{>)&i|Bi`^!xA2xp1t@(42LUOo_{tU?gvb zhDqLhj^ZE)fv*;uOPQ*u4%0oltj14|CE5ggNTrf&%IqzWAB~QV)_Kbm4e`<1croYD z@1}&W*EmcN!NoZ1@E)Jdn4cw0&QcX{bJG*y^}!;6%c$s8*7qsTsx0G_(u0Lr1Chdwzigf$nVaE3^D}fmgo;oB+1wb|!{~_J3v} z9K(EkPdG5JOlB}Jod1yhrNZ(ujA1Fuwi^=I@7AdGo`B!mgs-Ljj>5t9zw}_sT#vFr zSIc6Oz$m@DT>Fski@fBfcjfEM=QL-nI-yZN)n<%Fl^kC3B=6^--+1`OS{7K@I!?H%cc zmXx;blKpZ;i}N~{?YxEZ{JdM6`=u4j`djV}QCu%Mh)z zkB&xt#Tp;NRFfQM`gv5@5GbPSlC3)2*B*=@0HYi2jPW7o6=qE*7{ep_sgE9OivY*8 z#XIJZ7^o&2PNw@cC&Q}d^!S;pxp&Gyi{-ZFL?#(*%YBXIhwbV|rt6X3u;m>;gxd+S zwG+8^K-^5l^LWB->F92MoZ|@3X&p_w+UYoft;H!qC22v8?HT#W?nqvk1^eBaE-J6k zwZ8An$=dstqSB%IGM6XT$9DSrzVnU{ms`h0IbL0yfb?BgkLbG~csC)czNfd^t?h9} zMjq6)`lG>l@Fwl`Du{GWEp^FH?9cdl*ADDV2fo7SeV=jOd051+CMyT=AnmBImGvn7 ztb=cDUckPOj~Zb#Wve@A(Uy^6i{@7^t96|kH82i;YP4l+796EDhRrtitdeY$&7Sc6 zN>Og!ZQdXtewNbfr4J>$;jiy2t2fA!O=UB}vO#4tz!FVmGr=-Vb=K*NDCv#~XW&4A zDsdPiL{c#U0qiw`0FH)3LlmXKZ6z+3N1gVFxUCM}DI7Q#IfW{6 zFP98ulKBkUd<)0V^FWF@{`$$8EDf=)6&nuIt}_s}uT{6#k499SukgA|D09^b0_eJi z2zBsCf-13+13Ezt6iQ2nf`E3$hRbEt?+t(mg@#ys@w(!l-abDA@|dx-C3@_}VS6#X zPhomc5QI;`oF?#|oD&osF0+Ug>#v5emDqM5>q3n>IMF6FDGSU@fe_}zJ=4vk26hU8 zIs{||cBbgiqdH^AK-rF3^^6I%n4hl^VwK*13F&Fs=I zYv6`NP!Pj>2vD)OEFg~?K-P&+s7XvVpwMePM5vFPy1jyA$egm~N(ByXH;=VMeeJ|l zK`A`K8@|lzpJmf&54db%eXY=m0!k5tv#l=hD11a2ZYvI2k8U?C)i9xC=~jvFZX+j@Z1?7fPahQgoB^3BMK+Bw@IL z0mgp8;{6XuK)@hCtzg2@*fF8fT=@uPE<`{8^&)V(AoyN-fGz~iDqg7@1`R>z*geS2 zIac5@Cvdc$pR#}i0{b9821@cr(mZ_J4?A{SMUu#5aPlpxUoBrq=baM>U1;y$_M3+! z;Ot!Ve7_k``0j(|%|2+}%%m~fj?1=`&|ZcA(6z?6Hwq(Ik>Qa{T%wzxfvBCB8hpVt zH1Z$q#TbOZH$4FX!68Rh!ax_guIUMd?qvDm?fD|k7 z$rLw^Y5N&TKF(K)G>REHQ7I5W2NWDqPTXJZS8&+wOsMvXBzyTUGeXGDS&zaSiysk6 zB^Dk^g&iBN)a0e#T6UgN9ODOE3-FTrgo%p$WATL;DHDg_iQitI4Swj$%=9J|g%%A) z@F!44ioK9yk)Ltv6H*|?gj9A{LYg(m#bH-wnIzAE_9^I*VL>%6#VOnuV>WiEbGzB# zJDGR8-?5t?7&yYgb3ExJa0uhAT1j>i&7vF7*Mf$W#t(FEeEU~6}iQhes?&NYHawA=Xt)LmE zJ>$--X1_E2V50dvaRCdK?A76&OKMgylqi7`c+&zt$C<8bdRD*DN^ zxL>W}kBX(@?0^j0-v{Z8ADA`V#+A1|68A*AT8**WUrtX(5E2{B3TAfH#|0Q@B?iHYm{aau!VzC^{%VQ8txRt3b`tPu2eT^@~Bar;ev3!&->YG7Q-( zjr(66SZq~BQXA1fqXg;; z*Ha`2Y6CGvo`FS4AEIKmzaX`dFy#F_kMNKkDu*ZD)Z-i&f9B8|F~;w09% zui}5$$~AwibbLJhX>^wyk-z-4&-JVN4pTmWJ8dDct}LUi+><6m_R{O;*KGEPG}X2C zr1#HuKfl!Kr;k~+VZOV4@^O)G@i@xoG08xFzFGDzd4~MI-+*3LSfDo`dlN%T!#`G7 zGKBGy%g|t8B)GrdPX8tLOZeAo&5@cc0G|`J?e(7Lryp%m28ZOVWU%!D8&r&(qqQZ{MXr+#(X%s?vSTHX9fuWzf^6 zI8IsL96d#DYPP-96=~BSh1NA4sL(3DBa(x}j%Gi&aeD6)!FZn@NrQ}L_~!V=j{c#f zh1kOy`e+b`dI9oY=|^Tbv2@ar5-pjRE(K#1Qo*T3x3f3Jmu&^gtv#p*s@iJhvbS{b zWJM==G~f*lR2b+wo=)raAG(}q{qW#uh-nL)3GwC35lDBkrJI~WO$GvRMI2eXQSwd{ zC@A>$Zj>K)RUIpoCgpU+wqZ1StTLYwTDnP6t@gQH*cqwIzT#i*eBRfFEYuvh)Oa-N zP`jG}!-T4wP7T?wsajh-;Xo(_9~R{Ka;@HWlBnpT46t-K#QyAK`^64DORO4lSvpFx_c{6 zGVebdnhwV`WH8W?PP%|5T~VR^aC6tkc5)d~P!N%xA#k^Sake@0UU0Xaz6UZ^Jb%69 zq~qp(`9oVry8HFPkg8QH^I6C9#Uh}?V;`nlK%Ld~_HsrrUC{k@Y}fPYv=@AB)5N0t zJw;b{OVEc_UV32Ne&@pISzo-6`9b%QKCkmNmqZ|RUxXm$IdPg|E52ahiO7bKAGc^Uj zV(U-b)e*;mwawlpmscvit{BIHG*kTS(g6JhtV4!_HjxfhlV{J0$&{<}<*(a$m_AY^ zJvts6^SdVon`dq!G=#(4eE}jFozU!=)?hxva@ssLE`%d`H-(O@GCJ#I;k97{Ne{k* z&Nw+pawiq-UhN4pAzr0y8sI z`R=>b)l|I6d7uL!Zfz-o89@8NrTF#Y+|ZYlq*Y9r5{Tl{k2!^2hWX3EhyB|{bK7~2 z;W8Q&p|&-WdxLvKRC<^j**tT5E+(y}<;x?n>K95h!Jly0)f1k>`rg?gJC-a7DJs4( zIY_gA*l~oEq7qUY$ml#G6rjSL4VS0Z5F>ZK#ga$|+=S3b_xt@IMcW1cnjKRjEJCqE zL@7C-I>Iy~q*z9ptYL`=wVp=#6-LeF>!9%T5yj>Z6zsH23rjXxnkTg1L|yl-Qi?V~ zDg7eSG=FFh20+I6;gvVKd94|(7b)6la6$ZgHi}b~YRqcG$1?VO5y!Ew-p&5!Hexk6 zScH9;KMBh7T61$c;#ip5vCRFw@JQd_t#f@uo<}O4lN~9KvRhbin0Wg!icQRJk&QuF zL2IT=ZyqV+Z6*3h2#1T$99i!qFeUH`q%0WwsJHrP*AO*899gPIixtV@iA(% zn41o`D#==*OKtj9oot0^1(G<$YnqK(K^lwXsWV;Q{dfcy%2XJTWU+Up2u&Y*{B98; z@dd%o_PScW;l`1@hC^O@g#CM^!uvRz>KqCTtQiRm?45h}cpa{>Iq<#Sn2p;I9*)8{ z8j_mg6#-cn_$PT(Am0t*+gs6CV{qXHWA^#bl@)E(IaO_CH%FA?9kt5II1a-q&Td{4 z%ssu2RQZX=Vc}LCHDm9AWy(>7rSuo8CPhbkI?tD19m~ofJFy)BvGbP?VP^|+AJgbs z6vrLF*{BWUO7MtE_7}$K%Ft8Hw00L0NyG-4So>%aV`UXi!r+W^GT)2_gn1n5iB(QL zm2=#;T((O(4qQGRH+nYXBz0QV$r)JM9*q}?-GSlI&rYhB9CmF#-k|DbpEt42=z(3F z%%YZ4>x0$c5vc=8p;nc2sjR;Il$qlnB@~n$qlj}!+LMW=u9njc2`b()T{H;Nj1Lg3T z$iL3=+c7ml=9OlKyfTaq!9fHc4%D)!e}MIe?m5(_V)v)WqzR`fM1^tl>hWXwbS;Jy)x({gIp*cd=^Ozy zh&zMRM~da!^j0MfdX6n2w<7(s>2Y*VK5bjqD(ATHU?BN1neAnkWwdS7^vfx0HUPZBctjY7z`&M4WrHU5Vl}9Yq-J_7JZ4y=Xa2sEmjfG3&{OUaZ`I@xs zqGTDYZSig#6tq1*IPs=aDaxh(&rU6Kn101RD6vP^j%5|oaB%_TjIAV=ir?D2fHM1c ze0oGS^khh9Q=e_hqpkvuk+|--Oo$=PCtB|DDf&bpM8rSi6b;kW&4w82r^Fza3+W?~ zW3v*yPrMn+eS|FSfSPhd(PC0nB5|J5wQh=Wl1)k(o#k1b1v1-{jIL`iH~!51Dq!Ym z?&)oI$8XYcBH)wqWTWK*G{D&v)ue%RCB+1Gb25|CC{a&>5BXhvr`|?e@R$}j8qb`( z*Xtmz)vjk+xABqA#FXlyuF$2-TS+o&(LXF^KTK;jQ!F{x$7+Q=;VDX@;t}+pKWO`G z0c^h?$AJj5qE*3RfX2R={+MUTZQl;Wmdx;D#!l_edi@ypP3gFw1nfIO7V5YVlaR^! zYgkzDSMs$2Vy8`jV7LI5Z+8QeC4iP1)isBV3w9?Iw|U~{Tk?wtrp&Z2OHOEov9L#o zYuq|e$#{Cbhvzl+-~?v;k|{|`-*Lln2_hi;pjLCpKBRL-SZTF<;fM21QAGi?p74Sp z3!+;KVeD+@n$g#m4{vRIBipk1KNH=1g8w~7HXWqPZh@+~sGvNF@>eZT4*)R#RRUC0 z0HiRZdSui->)i6QL`G85}X=|@k;bTp;YnOGee{Y#-8a1W;mVc1V>HB7Sy5=h&(`IwyS-4V6N~31%4JB z3Z_arURMqwq7*GEIVZ2wIVMSEAXz859aSg=A*=i5q@H+m0 zuQ#37CiIZu3U`6!tN8e}JKg(LNp@u1A}X>~zVo5x{baO7XX91fcEirmfL7@h@hm!N zlPEqZ15we`rf|+0B(6iZyp%w>Xulidtq_1^P7s6omopzA2O<0L;N}RVmZB-l0 z1)t`)-RpxF=k~0?rQ#*B#PS1zXe4b~3hr7?T^ncH_?#sW>vsD0x!w;Q6aNtG*@k`NNCy!jB}#z-*E%Fkmryo-!Qq zAUO0?A^VXa2Cq}b&1+{PBPZj2-j-F(hiWS_jw{#n>$RVw%j5RJPbFb=IWnw6&4ZR7+>2x43>dV^e{O_ z`!sO=8gavgb_UmFQ-%N&lJ%O2pahUIG|{;RM+wl6Z3$Gn7V_%3bVSu2a3 z+tO#MFz{&Wf&pu`kxrr0<5xQ0IPbe84xBfIC+YXk$b%lvU0)N?QU>9yoHu9o%kJY( z=K(%9Q>?{)7R~UKH|lVI9METSE|YocVrX|zq*W$Upx1VYXCl2@dmS+dt0J>Otzx$E z{+uKMeW?^ZYj)&3)cpc{;Bh$4g8WkL3Er^kn(R18Ta;JPb3#5JUEImIWf$2bQW+~d zH2sG~#A>va8e?vdH`(l&=0pO75U&`nAnqskl-k79r-R!X*v7f2?FbS{xUBpfW3G4I z@$Rr-Aw(*HNat&B&9Ee6rY2&q@$1*>V6a^m(3p2`=)DIL=lrU^30iPU=fCM8p4n2C zVIjt6UAy6iz$d9>*^E)ez;SzHN>~Mmny*uHdTWiTMq=7z@WutWRXH8KGbek&nJ}2z zwK-bCxXdSq=SY|khv-N}9cE+n2@;#00WvPRDCrWauc%8guN6&ti@vfPj+@qxCIIp=N^-a1i4$^*XpFe|W;*@u~PL^8an^G06c0=7p zY=kdS3L$>bM7E(iv0IH+d|dPF>{i~?yvxk;C>EYN-LKy~eAzUB%gF~HeIq}tEYZSU zhT?uGreKp19ig+;B=_3XW}#clLP>*UPJ@A>f$-@&Qu9?6vd=XhQHC;(-%r{E+LAfe zP^_VkvNtVwYAwnaP8`+hb&xd=j40iomXci*J?waU7FP?C?hGW#%n={+|seusH+1Kac|Ax z*~mQ^bo+hMw~g&A$8?RhDkw)oAL@LY+P4Il=)vcbAFkQWpqSxoQZ3C1d=Y;#Z8%)-R8j*PY+Z6KoN;q<(WnV=f0BYQq`r}*h0Fd* z7lKWest1N@TSnRG@g@og>D}qAItMwa;O#`JA1&(+t~7?Phop7$t#1X^jLKc&@pPN~ zHdd;%u6bx{)(-oyG~ZJ`G!9sl_n4!YY+@a)MNo@{`vOf$a+ z&IqS;5#E@^5PsWSMbaPyBus45sr6*J>3M&lPx}Iiwb#J^4RY$FC5q@`ienA&hn$!8 zW@J}uf(q72E5NsSvS$KCg(Wq34SEr-;Na#mI!r!JQYBV5$0EAN$i^=v+mojbg>~QkH%7 zk3g66K~Cx)igW_k7MMtX~Zo_OiJN`91pkqt+F zi!02A6J6_|Z0!eE(1$!jQeaP3wd`bdqdQ8-$i@|aX?)+2+b2zIkW?ML)mo2uE9gpz zq0K!J)drr4=0kBgupfFZI;gS!s=c7wYB+|$)yS#cF>B0aztL$*%XKTo`ez348~p~^ zlL3Ud<6#zedN>PR4MM}U$JXt*Mkjt7jn^7P7n42ZD#oWMn7wzbRS<*6lhC8A*7b-t z?j3_zAr45x_t11#=N00bVgZPaz>rsRXc7oJ(AZCxaa?{B_E3##$$ajvS2u)>r(`ma zMf{GM&Se&B#oZCw>9@M+7Ay8ZENBNsAB#|8OG_9y!Y3eLo*rTP=&Gb+&7UE z^j#r>9s8s8x(isY0#R54A-d9!0Po|*!}@;6^(uEt-uoU5sfe}vv^eg^ui6tQ zZTRqFG z8T?Ohu_>z_qtc?wDxr}w#>*LsT4K||C9Hf}`7#i+=;4W3sI`!R{W1KzZ~-CH#uCZ23ynL(V6(}$kx z36EPAKL!G}9dCLWJ>{olrFhoG(@(%-8Ps>~0{BFN%;T7qMPtT2`Uo)I5N{#uHd>Wj zbh^+0;66$fy%wh?=@9h#+aw%d4Z{eq+?EEdC-zEdI(H%yK#~e5 zwuvmBCeHaL%3dNE_K>S$ka5n@#Ue*&Y6WV7t85GxpC$U4SAB+gIj80dQ|Sd}~O2Gp$dA(4T>ckxwuyull`YU+cZa`X#RwxTsVi|CZ0zfzQLIXXPt>IRTkv$SOmAzthzaSaW#A&s9%u7Atli0IVw(w> z2ep8}M6}JhfU5rbV_=iL*4HSEicHh6d9y&mkxNO_r4iKg1>eH+E} z6L^P3`jB@fX~t94*;PkZx1CIuSo}fcr)C{bHN-h5zOT*YsL!WaE{sIKQOS89KUHSW zf#A>mEfSt}$p#sSt)Gw;&L&ol3~Yyd4-)#OT+Xk^K8vV9ZXSbap@yOO^_w3sXB;f? zoBx2}+#pV&yt_>X^f0t9jjg=mIf0L9ti0sdjeo79GKT&rqh4ZTu42&WmD=SR=)5sw zwjKt_Obo;?ZRmeR@ZnK%Zegv2V^*c97~fS*a6ypfWPVFrEncHvcrI2}bZ*tZ35w&q z(~mBAebmhBuf^L=Ha$+bj8~yMsaKa;Gj!rT%QC>+E@fxqD@+u%W;8M z<>5NwNY7IGYd|vFN>$D)6q&kjk=J;JS~VqxIn50y9C>vO9RR#)+J;pa>+F=rhH$J$ zy@uTp@jepHhn^x6~2 zXwO9UL)O6ED^ccok_sbQ?Wny?Sb=`F88#y6b|+=+i$M$i3dv`d{P0$92L*2-z@THh z!s!?1Pb=OMrEPPNE=tzjP%Q`NdiTCQJAAQAj1*B?Up`K<2JpU#F`e31k{8P0<#<=X zEvQfK^R~@O-fH+AP_r4*IsU=fKG z>hmRMp#$~u9SjWjgsp?X$cd9wKxvr~1M)jfzeL60Z`+z3HuOmYnsUU!l$m3r8nq)5Jie6KhtCwO1HD`EE&?3d61L|IB~Jf0mjBq2`)_a#S}fZB0KwP{f)fw) z4JyO_7JDHm{j<>U4|HYCdYDoDuKiYpN897m;y+4lSxAvC&+~gl_QwY?z>i%FG*noV z+K}Yp1E2sfZP#NG%PSLHflM;9uoaoKQmA{fm2D@OU)U?0K9B^~HMqhNVaZ5TmH+_t z04|g9gu%-wF~_sqPL=`VH$z+m99X2;6KQXA73|`RViZz*j$hDK$j^hFHBQ$9VCA;C zgH6e>P(Pm#F4c41ppWhbrZb62Y?uy028tKFQtQfKWF;RQIlC_D=S`bzw;Nv8`ba3PuRCo*oQaOU$L19KgJFT)g`soNQY$}q^F zt;-iuorWmD%HGh*UR%k<+R#qxr4&;ZJ0b_cg6V%v)!vh*|bZdgRI0Xcis z$$k-^?tOZd{zeBv7#Nx&$#Znu@%+$+Bu-}@Oer?II#;TF`3YRkHE*TVh&U$UJRK|1 zSFzg}mO}%wdg}Dfj9Cq~)4P~(zEtuJpLKXOI9=sAIKh~Vdo9@%^SCprEu&E$0T*+w*-7$O7t?c>8clQn-t!{DtuPh^`*%{sG;#>QHt&M2VNho;IWizN#S7sfN~0-F)|U#! z0VznSkOkA94WxhJV6AYvL4*ii7|)plfVhOI5cpf1zN(j}^9#$_7kTXhI_$vIcA!p225t+ke~wr7)V{eKMmQS(zRMu8 z{sPQMNO-x=q{ zz;E_%5%pjB=kHGc%s?+1znzZ#OXt@e^S_+E+>*bK7pn2g@o%i;zx(@>m;569+aJi? zUuyqgDgO!4pS;_@wEaL+`d?1}$-@0p{ZB&aU+RaTjPaNHzv!j^tJ5#!$lu3Hr*%M8 zO;Eb|UkZOm>5}H(^3$Jz{+Y;L{QO3V;LX3O{YP5+)6Sp!Qh(Wr1Ks=oZI|j#3x5{r z{<1I(%CIjM{#CO3|L?mVsN4rq{U@v9?=$32Ud3M?gZ^FZFP6ohA^%xu{>wlUh=U69 z`|q&*ub^Mpt-p_#5eEJq;lFWR{~r0DY}Xgv-=kLcAG&{WU*)BtUtSMDJaRNJSdiQT I-OIoK2aue`TL1t6 literal 0 HcmV?d00001 diff --git a/public/excel/Corolla Cross_Leads_2025-12-04_2025-12-09.xlsx b/public/excel/Corolla Cross_Leads_2025-12-04_2025-12-09.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..313ce50d28184a148430ab430bb678f357d3a6c9 GIT binary patch literal 13235 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 KbP05CeE$zxIg(HS literal 0 HcmV?d00001 diff --git a/public/excel/ROX 01_Leads_2025-12-04_2025-12-09.xlsx b/public/excel/ROX 01_Leads_2025-12-04_2025-12-09.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..bae4f2446e84a2aa7cf865b7b613083c982a04de GIT binary patch literal 15736 zcma)j1ymf{vNo<0g1fs1m*DR1?(Po3A-E?%a0%`Z++BieaCevB`VYyy_neb=-&=n# zdM4?vs$Kn+?4H`Y*YAHHu)u#9+Zo9_+Sxn3lLwNa0x!V)B5P)! zuV4TL0bv0H0YUsbnSs4My}ONddR(U@I3udaO~4D{H#=rJVnrsZfKV=IO&2_7yM+#E zpD>wrDJeB;fpz2spB+SDF-@dwR5@GK zGoqs@VJT&(tgHwNv|ya+uW#Jf%fMr>!NSnUx16K)Od}y{gGGZKYGjf1D{{k5kC%GqZ`$fH|K%9XVc})+tP&E!**JbtjOz}Tk4%0KU{#k+<3Y> zKfa=;U#Gp_FZ7caA$iC`A>8Wgf)#gfar<>(M9?@x<+=6Ca>^D#Rkxm+r39nH z*4VcR%TTL!4i z5fV+3PVZCXnLf~+B_Ett3l!dCzp$@N(6%#VK$adp{oI|$_$SQYU}?pKfiQmr!i@3{ zm|dKl?QC9wuKlzs7s!COhdr40=I-7h2BR#AKTy}X@nIVz#+i7?ULQ!+5yWFUQ z<#iNj*_OM}M|2GupUSDj8K24~i$~B^E*ZOp_n;LX9T(jE{t*$Ojl37k?8FlZ5rQA> zgEg?|BG}geA%*~4jVsqntGc?<^kld0YBnQH;>=(v)o%d|l3$rXbE60m5-(eq03bTrk`h6y zTXkjI@DRrMbhTSnd=`0Z^~P?-nkgRG^{(H=ECxP}eW}2x7<<=zynHSa^A^JabsHmQ z@u46r=4^B51;yxPd+6!-#M1ZSVe@2vEwJSXzYaR}<*@!?clO5IcjZa%{6x3TuCC(r z4xrd_;ro*(LxQTk|6%dV)8X^b`lIWM`?}Jmt}4b%VP;G{syOPQ!^6em=@{Q!$5@?H z`wHI@!L#SliKk$5w^&+zef`h+-Pxau1-uag{?ZOrT++V2JVyi-bs@)FKMOWtSl(e| z@+~hfQa5GudCq$`rag{4&gJd*Joh5q%|4wRyPWM-cVEx8pW?gLhb*VNm^kj>-nz8E zjQC4=QaX0V_`x@}@+`enrJms9Ya5qL_}+_ZgJY~}VLsor*3M6)>}(&|-k3Z*bQ?7J z-rhVduP<)rz90KW9ASh)VUiHfW*y`FP~Us0wS$UUGEY9846cXocu7wEn`r9##~n@FsK^Wfu}e%EKtJBfj=8GyFQfND5h% zQK4W7HX^8$HWaZj3%csC?WyLh^5jk3Up^bpVNrS?$6Xd$q=?0FvWuvu48&u_n^J%6 zWYA$m?q+zRMa0Zc<|q8p$giJ-4(4y52?r5uK?b~NP={)IyRPLvQa4-H1S4P`)VTTD^&G(P_1OnnfdFYkIle2|-71`x=+Ee~bs+6#k4 zg;+QwO(+i>fcL<$MxO|A?@p0$d_RGIT--k^4orXq5^SdRJe2K|UIxD!wm-j`Ch&ak z@1^WxY+M}W9MUOXC~_Q^9j6dCT=88<4|_+u_Aj3gCeydoh%-nk+iL>?+k3s=|2XYeg}cQA6h8<{eSatCkb(--^Ho+eFQyOuXlqi#g3j;TBb#< z*Fhhxra|Z>mfcXd108i)0k4wX~sV8S{>{1WwR5E3mc~zOieY3~4 z6nsmOqa{5$THzj3ITXvrAD2*Jny3(+l?WM7;r%=0X(7Rcs*qnV6<%l(?&SkViZN%u z+osx@hk>}Th6M9)1fFj1V!T6lG_{i9JF#llFe=91i z4hJFX2z0yeR{kC0<&a?DRY)+S@%R&p7embM9^K*y1T32V9cw^rb6H$-BxDl$H;w3= zFjt$*f_3v%;XF(_4#S}Fv!o-Y9FwBad4fn?`hZHh%>#WRgI|Y?#WVkKLMvB@x z^8w0sa->Mg%D2_gwHQ3Sf*d}qJs*~z${ma#rv5D8)K8XdF@{iUCf6u)t<11hq(7k4 z8CwuQBnK&!0T;}T2JoQ995*64zzxJ_=RrA($DzvVh%(Rh1FH}B2XhO+3T4(jX8D1; zU&O`BdyK&#dUam=<#Swthq1J3F4DC7LUjSpHru>XCqI_i*D}mO4mCi$LpEk%ry}E4 z(Lgd#{b5IipMx0bxyK~G>S%|N}!l{SBz zEF+`jvK(t@eLVZrqCclJN<;p4Wifvw9AE$rYYnr4t$I6>tWkwB?$f|C97Et>#zRFV zIp*ua{rwMK(Wcv>k$WO;Kb1;Gb4U|*K+2QwH}hX`ubG|EO;_DbD56$sLi2uP>Gg#6 zx;G1UK?5io{McpnvO24w-iR#^Aku*Z_tq=&5?4bCaYh5|4+8Y^Kagk9KvS-_u7n~a z$hW96%D2ce2s%oT>DOMAK&A|4KE zA(WQri>r0=_wEvBVp6xs1C+grFeg>Ez^@ur9mLh5yVXF4&t{6vz?vNWkl#;-8cXfT zmtgM60}WhmyRElB$OT5$5@hAZT-5p%&m%=t0#${PzD>sSx~5=>+>;vf;%_GQH_!=d z>t`qh`i_AP4OE|T4kky~>ZNpt(uq7QDE5T7h#DwvL4f~(a9UP@Ei=EzU@8P!q|5P1 zFqGVJ>x@Y9f)$j00gvZ`lI>?6G=Q@&`9hc1PB@XAh}Iu&1jW+4|9}rPuCjcRC~8GO zS53HomvaE@hl6YA_yV8Rj+?y5Aw5 za8N6}KY4G~7enM;h!G+O6?^>^G^m1|(QM+%htKviv3Q?6U%~H)N)vT13^3N}?eHu? zkrtojs1$SIe)a)ZRv>Q-%OM>Znid|{T+ShAO58O;Ta?mj4upe~0m2Wx4-769#_=E0 zjD;nJ`p6oTP%bKfgJR5S6-NCIO-2TCoX+u(l8lL_a1b=b?WvBd#I zDv(0OaKXwZ!73(w!sB;(!v4|_t#+gk%XVZCPp1&5&OdCFDa|~1Dw2S$Ffq1>0m}V%Fvv>W{02`!hDH0yt^zWk;F1M?a7=v^s*k zuVN$CLg_@EriN+fn1iL(Uq$hD4m~q2_$M zUa(O&0nG==ekHgan0qcH#b!72{Yn}% zM0;)&Sy?5vV}gx?o>+bS#|LvlBx*9r1<4Izd1i9WgHhi~fI0TxQaTFhMB2}|s%e1v z0O;ult*U^=LC)%u4A_Q2(4)R_^=?sP!!swR5<=WDpvG#;!9k7*>`Z`BJ(r{Gw`vhi zo^o03W!R6&*GCp=jS5GLW5ftMtV)1J>IGsoNTG5#DDtF)!4PdU2cXJ+A~+N1%?Fzh z+S{T4T>;jwXw7rH=uHWT(-kQ4<0|#@S=!q&F!#~kuNE!VLB=fLJ}#O{bab*V(qF@4 zM6oeQ-wpR?dWQn16M)MdyM31_T7_7a&=BQWNiZA0jw_ z5bK}Kex-X>?sb?`83QT|5}awt6d5a`fxY;4^$gucr0E*|!sy+5P)Hq@2ed(zm3{`; zNH?J3d&SE_9Jciv+-%45Q{|31N5%SCFF2ivKoeQUO~rU6PUQ2l6#) zc0;IZT)PZAVHzj`pD9Tg%PCm%@rAwUL(`2V)us^9a`I%VqeKiFy&^yP zZW^Ha;R0%C;HTA%hT|%|Sta5A=jv2YmL6r8&MFKn6>v~vA?!RkI%uGPlWKP4fO;7k zBFvw^Y^fTYq=r(}>;Kla2&lKEs!5|K0FDPn1oC4`1w?nbqv2(dWG|7L2=0HJ4hR*I zTC%~fKSrvSbzdYA7AobcIK=oWpcSitR@A81%1*TZwT7$ucoCa)c0P0|)yX&*Js(%qfSt(E6g z>Ninn`etXQGI(rCW7v)7)H^%4EXWtWTB-NOR(+*oQe`kM)gJ&}-78laHKy&)9@Fwp z^Q*$`$Q_p?VPdR_$RqS(lLCfP6)==Wstn(efKwdw07L0`+iHWYN`I+<#|j>4r572{ zJQ#L6Bg1j(-1!kPE0s`Rvg2AnXI$T z;l)FUNx7w6D^ecLAs?6*E(HAkoi00C>XGiwj(#T}X#^fiVH#H-Z20BhAng?|4#}5? z^B{PYE2O)>#zJD)qexf=-iOdb9kl=hHBLs?f2T}f4EV?C6!~;^=mK92T<9<})Hn%T zXP80NIQ?49JW35nn5xwLj0zJFhsV?X1k3aNm&-QKZ)!^?eU=7|ZuTyFGS&@h4)F1? zaTY1y5;QUrW9NYZflY(Sr21=)H7_+BSMTM2lNc^wgcjIG4HcyV7zMsm8F`B0(12lj z)v1sWQR>kU73%$R&t{?F@}fDY&WF+ieC#Gm0$&qJhyrTt76V`me|1!4sV(LpEe-`w z&@JSU-^();SDru*qsBy5VIZYurUkw)eRTv0d|PiRTpVx=SRN(yVAYY*a)yylxq85<2OanWfWC1`y;ISR7AuiJW^ zT&Ej#5H<`Y0d;{p9*(RP9MR5KsYbU*^ZpPlL06`(w|S=uq@>(?w<=G&YOWQ^nOEc6s*vp82fy8C+Ih1&gBT2H3!8uwEms1TKtX%YL?RjVtf ztZ=2EgM9D3ZZunuQ-atZ?J68rtO|YMD+C%}?y-Fs_5@MsTA;RX`>@+|?QC2Q(RBkI zy`0{x7N1-l&;h9!$@ZP!=-9B-H%H7Q#=_=6%epr!5Y*Jc?Mk643u)+BhQms2=W9xh zgZDv$$n%GjO7L)wok2j#x9bRhPeM736|PdA%EF6`+`W@0{1H4InE}J`-MGI!gJ=#( zs-i;g@%Fx#`SdEHpdcnAllOl6@_chjjBmG%wi`TNG=IJ1wEgyBQLeQ;!~5poyP9na z!+HD5<-A?H&puQauO`!nyQ?X_3_kC>kzL>CvmVgZO>^rmG1AVi<}kSyE?WQE{f@ce z^Q89VUP{rPZ~Tn6t_>$cb6_iJBnMr`MqKVU9O9wy?l#vQ8}B3Uq>=lF**AK?@EJvK zu-u^5f>VY<&&(4=Prly`_bdzS&9S;+0H)y*WSx>acC{QbWRHEg%ij-k= zEj{5SQq_(T??~21*xx$-Mu5xo$74`9r ze_`Mwj1o=c?6~yTo^8jE$d*u#h~MW#965IV!w%tLlcO0-boqJ&8?0>|)GOjHaR>=c zY6vDg3`rVEmA;G#^(2KIRavl$O6+tYNMNVV#q^>|qI%RPJ9ow;wF*tU4S-9s=Re?g zsy2{EC7g8{v3~aLwm)_%z?n4-qF%cdm>Qa#MD7E~=S{ZWfU)}6!^gvMU z`G9i5M>)a6B4uYZhjvJJ&??xjX8z(^F`jyTu{gV(hZ-nZ(yi~a@niSYc=Oy-kP>f@ zvo}OAvjdVP%N`_fP*(4~g9qM_;ccNSleGRiadb^ofAZtU0e8$Cfb1!&9%q>F`g>&E zK8PjktIDbRt|<-2p039q8YM+Iru6t=-?!as6{5SN1a|gJtvo(cFI&~cwVl($P%g3) z8AzLco^y>gr-M?7y?nwB*dfeTyH-`N!K0<8xrtCNs{*k!QC<7E)!A6Q$$p>@CTedZ zh#EpI=TVF?Kl9xyHF*V9x&*BFOfjd>&m?~_{IGAk2w3BCjh5CTjdZM**c;fxCpSdh z`1*ck&%?aMqI_{EUh`6!GF%;#Mf1x`RIiBB8`qKrekCO;^MiEf#~oL2NpgOT{>+YJ zJYI6F>1cThEnyP(J2deOyW0p#slK2iBBWi=*{`2V1O!QU@W~|l)rQ_p@hg=PrD)l} zL#(Hh%|dB-%nk@l9+Pf~9n6L4 z1rnIWtJ)1ZVOsMfX;YnRLGStI%2eq9GU&UKcot9HL3i-rID8=Id!5ZoSP8@!FmD!~ zp#Qn7CAq_$C=3Gv0uNjfd0nvu&IL~92974iO3scJwq{PR3nJd?i_u$kNZxN_eG%_j zldwJ^+jSlt)z~q%VCuR47~Rh6w6zdTOYG55Sa3Mi@+&pq;9mjXnuiU5Xe8v<2bb_M zx`wviedjp6-~ys}(5F3}TdYo-@m{5ODkSrV%0;PptIJ3rBoBE+t~nch{m4~dZ@=6M zr(#5pTmE;M?Uap9L$%x9?rMVPwdn_Xf9p*G+QIVXr}OV&tMMW>k5$cd*u&b5b!>QT zb+Z)Db#&4vLtpm}4n86g%UT+xihOhMp5jr5NvHqRRwehaG2-yivWbK1>iVdLtNLzV z!p-#qlNXK{oBS-=U2(Mw(rB_58oYibqtfa9*HkZW%*;=7N%ueI4owC39*U?MJ8@8$ z9@dL)%Je!N@~cwqed`nUp{ne;-Ad9A)!g#;RnxV~9+n3e<<#&qu$|Y}H6|kU2!g-4 zuLw1ksbY)L@vn(x_p~>XC?|*Qi^*^NIT=F|OfW9d*+HQ_3f4>f(_0G$u7 ze{|H4do&*mmxtDUtB+zPGA^E!e@5`qFD_?r_12v?>(yU$Xoc4UH&mCTn$fPLl_428 z>Lx{PqLrymKS#r$?)EVh$r-M;5*e+4-jd^l50_dbKTRz={~q!^$A0~sr7%{R5?%H~ zX=UA5=2#}=^rB7jnx1WbD;3iqb7wW|a%?G&)NT~Cm=rm4F>4EzhchuoImGVHcdj}c zY1HLSgULvx{G4$%6&>tTneMsAdk!8MrH_PaDR6XMJadQkTY<%)eb=rG`LF^E!C;Mx zw+^N&fWc&Ci(=U4+)w=-w$`=BR#W75`f`4861+7kCe{se?sF*y?9{{`!7LhCxU}#X zJ}Ts~3{hrF$I)K&KS06WQr|)7&)G(lg-srqgM3vA=ip6kWf?&L1%r|wECTZoFUpB+ zV2E;i0&G)$M-q#>$-wTZZFjNR-F1*vf_;xx6#vOemY78^u@@1#oxgJXJ5HU%%5tF9 z1qj4;xHy`?Bp*B5mjgefHJKF0GNm$R84{Aj1erv%y)uT+@F@Pm9qJzilr-M0&HbEo zapD$K3L-m~C_;`D(QUDxyX@y2Y}(ILB7!8D$gm1Eu*7%#0&|AmEXgbQwJCW*rsIc2 z4IN)-dCjMg>#K{OU)n$1^*-r+dRX0D?|tGsY4001d)J<%0k_NM;LKOXBRZzDsxoR* z;EowfrpZhXB1r7)>8AikQy=wq&az9+-4m) z>-2&XnQfA7?h?#B)Y3mr8WLHAni#(vIxJqvabW63ue&$1)vM~}@=5K+*M0l)p&}Rs z(?_UUw2t2tS^LcXTU~<1QgJJ9&5mRGjmpKq)&uICb|7{$)AXe!7Fnz<@$4LV{j4nY zx%c4P-sBCT@bAv#o%D>|5hU1ni(-8r#;@e=aZtIlyIOf7iTC{|y1vWYIlmhU;^0Ru zlBcvp8`MfP(Llxe(x*!{RPtj7J@nz3Q`?H$sWOUxFXS`6qiF@0$|d(@qSfvX(+JFK zHZj*wzbnfmq%5<#@N767ffFPur1(DF#ytfX0NL)hTD9!F2OE9(0nhWhokIEJge&mV zbR2dKAqBQH5o!goEaEkVWM_?q$Zl&bWquMI#xJ`P=%<% z@F6+b1tBnzpt$<{qTop!sW4(2#{vy~ctrtk8=r1Xd8+aObffiLV&Nx9f z#Pu0tYU$k?$fGa}cEeEVh;FQ9@7o5DUAZ_vs$wX6vmVG8NhLIohPxJ#Mub(=>#Lm& zUBfk%s1E^%^sF0X)90983aD+;8Sw~eZ`Us|i3Imip;2WKw3!E7^SCN&l>_HsC&b|i z$0;j_$)2#H{AayT#i-dgN+iKe~#QWxh~ba27}Dcyyv9 zA-|P*+XXULhHU$V3xgA8eqW@}Oxw7yfg_>|zi|>Pex7ya)36Yrde0Y;d#{RP1u%>0 zG#%6!_AcRih{m`*eth8cu#I&s_HhpNCw>davvk7a%@CjW&zn`Bhr9Of-u|CRirLU% zw4T;=R0nMy$3n{tWk^w}@(u&tNsedz+4*+9D+tQE*=e@vR;CM>$(DJWedRv9aCss6 zqfD3Y0NNRO@jp2PbT7LTwqn2T*28pl97{v+tRBnDesSaPvnL47H{>mW4d_)Elw#@; z6CP(}&v(f4=NAKCOSd|H?2`K`<~)nq50Qkv zHVl52RYbUEU6VRTAWo)SQ)(CcO<;w&dCRMi=W9=+PO<u)` z@sADcz1{Mgwxn`QnDQ|WCL?nfM)8b?=Q{IdLnVBj`ttU4LkyN;KyO{V`MjdG{>O0q zb>0slqF82?G{q2ZC2g5(K~5qs)bq8K-7dNyy*7X5qAlDA6Zb#7fS8x|v6u zluaeih<fr9m@@a;32bZ=ZAz*N^sS;t9GP+%EvC`m8jN;@F+o7 zXKBk)W3cjv{tK2kh*#al{2k|-;;>G;R&mMo4TA&apTkaaE*LJ_KtnRaz3+t z$@Yt$+u^%qw5`lwWM-#o?d2_r8|HUD;Qw@plwHQidH@JWyFLiWn}5BAI(t}~{CfXf z);Ww>R7ZP>?s?JA3wRsK;cbt`+D>yicj=%_eef8(yh*j>8QYW<>G z^h3Gx(6v}JyLn>#kfX#mXuOI;077cs=?cS8)F&3WQh`~=R{v$%^tqhLg!Bp@6HnB% zhU+VmMFdiPMod;IF#(39Vr9{El4iRodQTxwkkw1>c00(k3BJET=7rPLZQeryKNuys76TntkDy74Hlv^gs&o4*NH0bXb=-^M zNfq}KXCYZ_C0AqVy?;)U-Q{0me|Q#1e!9FOh-qD`Wx5NL@;b~{E*Ac(-gZE%CwSTZ z4nGcBReFO))pA4Xg7^#aLMd|g^w5R$(;j^ELjuiw!nD~PMSSm%hz5$bH;2jh-oZ=> z-A`b9=Tf)y6V;I`X1v zeIWz{VOa56yNQq!kGMe8FTV*I$NDZ7DwE2H>M5<*&H2n?tM8eJb);=p!{8gKV&v~U z8#HS$$zb_Ne^z76yKf-=Ny8_m4-Ua*YJFh|W<*0~C3a9huu!Yv#8!!+L1@uvOy%Lf zRXO=-rX+Qb{mVew=w`8+j_VbN#hkOYGW}dq8cSc20fKsE4M5p4-}HyoKm!Y1izZC2 z3LU_aR9*{T7E>!2Yy`N@+%is>sU(E*LOYp@^{l0HtXu3ch_!)*7D%7|O}*X(hFNnQ znU)2PDQKp6s6u0}JP1rrxu~}b%#BlYT*^_K{RGzv`+&VOHQi>f5W0?!VLcF)ca;N6 zu)+ew2oBW|P0?0%UugBcg7Q-S773cj4Er~;J9dqR^f(z z!`u!5A)`CTWroOLMJpEU;Bu;xFM5!7!9N%*sSAnT;S_(rw<2uQEn_PV&psIZro>O_ zD>74>_~X!2^jULhct9^A)uF)bZbDnDIu+~A%7K~0m(I5QUE>J+XHoAFThpzI-jT@1 z+6F8+Fgm^z19IOon_ncqZqOWnb$spDT>d2n>#kzYlzZT#fz9I2=1M{Gpb}nlqR^Iw zdDmlIkWKMbPHsV8aJx{^1YN|APm`mrvsDPK{@YzfWM4y{i6zxF0!3;}sW<{eD$NCm zaC1+J_AppM(3Dx?<358O2F`q!00|fSu$xPmkftYA=r`~_F1~HqrSGZX!ht;{2{7+q zLA=2*0bGQyICRvhC}uVM*)kJxK;%f2u03`r7)+cAj}?$cZ%m1JX!hx?A_p%h*ABl@xa>5Us2mLK=gKe_e0E+0~k_*7t++2iG%ZQ@rqAS~jKchP9Ji^VV~VDWx(mf=0J z)+%@6*jofwAFX}r*w5-+L-4Bk4tL^U7hD$oWoY+2p>%zmhf#nxQI^*q?s5v>)_-qz zS^Vw&LCPtlD@Dg5hjHPGR7tqn3cH|+`T8zb38rYTrvO`5;rkWcZ%D;Vo#7i&xTQTW ztN1sIb#@y(;w-AeD$p1?jBwQ>lSvYxen=^Zpo<(Td2>lpW>VtnkunDFZM&`En5A&? z8Kpm2C-pI`U|0eON4x00;3P(9O~-~g3OKMRC#{8uVL!&Y!yEP}qY11oQI}^0_HNP4 z@nLe|10>4eqJ)A6hahtT-h&Wf3%o5xHJ-hq>SZ}gQ?#l@g^8hs?8{CJC~f1F%3}?P zZD5XPQcF6CuTg!=AF+5@Iia*v7t%>~;dA~I_#seh%#9E-$R;qfQO83IB)G2BM6W+KaL@o! z&3tRHd3$&cyi=OkYvYL-W0mD_Ufl$RjiD^nx4E#em;u*JDVMmHJae}Ygua`%xgw&r zA7|6m>kH*r9U5`_85C2aEM&u-qi=YadTHSyZkNjr)UHMWP85tu-ywf=g2MGp~aHc7|G z-A~> z=K{Vc75`Ixa;3wQ(wNI_?_L-_1;76gk4zAdlt+5N z$Wpi{VsRFI4>964t(JGu_AG`RuaS^E7Q_GUo&~ zum8cv%tZF(YWAn+sVJC&oIi30X=aC>ncOqe-AMD)>S}7+OMNIp?J@w5Q#B`dQ}!&6~o=p zRJHFCXrx>QH}}igQ?;Itv;lm7Bqs%Ypn5_(c|x8v8@Fm!0*bpr=2&q5+e>ChYs;VW zXGsCkS$-_|ZRSel0*yTWlPMDJ4G%1(Jvw87Oer%Acg);${ljgQE zx~^IJr4x9~ z2)&L9ZZ20d=-YZ6JdP8jwPG1^H7Ijs`H!G^1%0$LSPQ%HV|~D!Gf-F+P*~DTP||;d zvCmM)znKdui$`n(D*@>dECHcO^hc~NQq8t@A6ET0VLi35ZLta^4t}Fbr1tyEpmOh< zq!Wn{UIZV;o6*Sm2=Wb{^K*~H$j>*8aPSrFg?`^~atHw%YaB}MyV%jr*Wq+WV`nKW zb(%x@#7aU-Ri(+*=vAJCoGNDyp|?xwJ|c_#b9}eUH;e+9< zM(a$KP0$#Xw1HMkFwaC#sE5?0hn<=mi~^6F)~qO1{ynhho|I)Qp(IC>|Isv%VKl=7 zF#^sEtU8wQyJqDX+>V|4glS7ejamupbz?`w3?kXf(ugei7wJMD4L~}D?K?vGC{&DmD}KmpZ5P|_nLO#gWVL90#xc>b z#e!B*Vtb?FiPMK%^9h<>TLECE3huSLk}8&AWwb93%k{#{!}}fik9F#bUb(M1J?f8kZ1PqJIcT zGK+8#7Sm*HzH@1UPn#|njv-jbGA3dGj+=fvI_b{4y^w_AO8rKO%dui@}3G}a0=%~h>@k7=4-Ne*W!a}O$sPv8 zzSDqH#GN)7H#DSq=Xb znAlgA=g;I~6)E84Ga?COYqgcP9lQ|j%fy$L;qG0b4)tt?a^MJRxwEq?J{(=+NzM@( zW2V_sj!Sp3jzxf30)>H#i5Z z=N*rLFg5|<#0Gu?*EW8Wy|#$_yVme8bY(2N84!bRf>s2E+Y-|g6(zTN^K6D;m+)v2?av1*gQK&kCu5C$H!# zQoNkvE!45!A`kC|X1o&?->?_}4;3vy(CEyhXCfIGI=?CD z<4PZIa~fRKQKTK3)n~KnviBk3E;CGYuh4{tf%Z@Z{no$T8$}-ACd)QL=Cb>w&-v)OMBE*PCB9xVT*yA|ofP6mv|h#ifO=l$N9PfcbuRMTwQF|*(b$1F8|uF+xcNC+ z*aR7p-(8b`S_Wtw5Ks_8 z;Ac1cf3?$Z0sp->>NVs1K3*FzX<7fuKmQ!`&kXd+^LtSF|M2{ZnEz|A*O2^uybkty z{H-zcpX2@68v087dpwH2v;C`4^iPQXY<>KTI|%5~{~7e(jgWt`|Jl;_7yA(~WBkSb zp9a7G>!DxU(|#YX4{ZP}Yy#8G|Hbf6l-$|=mY@Dq^v^{0I?ivDGXKu@KhoNta{gTG z{Yy?a-hW^E{Zqo9b-KSKNK*cm@Sm#P|NpbcV*FzL_g1BUddQ!fmHryB{_kvmZC(0P z*Ii@-4^kJ(Do-+CcF@yBax1>O-6myDJ)#Vrd%A z%7Z*$f2$PZAUJlYya4;HHdu3uwA#D1$;qM!25tI!dJtHzBkj`o9@pFkYK*PR_5ID4 zFV*Wj0-y^kI+Dl!Kj}ub6wUacAJ{+g=Wc01>|r}BN|)z$&M)^)jvp?9Uu`_!pC4b- z)34J$?3X5X?;QDd0q7$C9bH3Pd*e5F|Pr+YB20c@A9$9Pf z3XXns>cxg|pu|*{&gT$?I6vN+=%`bC-ZXa2V~HV_xD^P8rfdn|OfsI|ViCFpG8&+mGZ5zw*Ot+#>tM?LsxE>eV! zQ1!K{%R$*I`rW-eYryi*Scc#kGACU8(1ueuO8If$)l(2Z)Phhks$>be2bl|>a~yV3 z-|l{4ZzNXTk0c+So@sTKu|sfw`1u3hDuvt}!a96Bb0e{LstAvb{@Pp}MA2?hp*LMO zK-ESj>bBpYTDx@uI$6HYF)4!ODRm&njE7m@*F8$fH9no^W6a3Ubvr%@G3iMq*{P%$ zHmr(uJd*4=INgF1uL)RH^-TeB>GH65LK8PH_m{oz{t0puOsu6C0OSAw$f*AS*~!7t z*7^K?&a3$LC2T?<<_#)`=r~>=i%-7^=2;7n`SjJ zv6;ZG%=R8P=dSVP$C&Fk+j~B~<#sFGdR-UO+ok+VZnjKguZ;Sgdq-Q}EDZ%0hW6L< zXIrMTTh2yZ0(=7J*JXuUx^E*Ve4~*B0;66Y-h9p8HdUOIikKO;&ana?U6%64T$-Dw z6bNo;Dn4_)Uab#_lo-@rQ81*I6DYjWJSpEi=AXm5Z+YXh3w%U;@u+HktX<}{IdMs4 zn24W>{o$)yzqCekM%^}D?04!*y|wauvOYFqba|&C7J>b&%Oc6vaX*HP@cP8QXk|Nc zu)Q_3bGSkf**ti2?oH5k)aJ=MGFD}kL?$IUsgx06Fb_dhCqU1E*zUR1J3Lukg1zbW zhzZ)~oyp6mVxO78yYh_wDiE1GHxbjRIZFT^D8-JM)6K}s*SPks2#fZJrL_C#vJ~cS zzkBGWUn;IRW%9OJ`uR*I3`?TuxE!46XuyWKhyg!RUxA>2|=d_QJwh-GASeMlp!P-qj7XwhfT z;5aAf;OT1&B&s7Aq{1U?Br0p*;ORQBt=5L!iK)yg@%NIm2iuYP`@Z5r76N6_FRNQG zS#z+aQYmoNFNA|+n;{Z1M#=o3#6zs$q6y{@!L(E0gjKSMJ_F1;z{Ig_5TYimkfLh# zzypucCmablf<~nY5jj;r^*)kKG=fIJvpxeLXn+#u)50Jqvt~xQ|DpBioOP+03)`rb z7STM$Sc*U9A;MCb_5`uYh%=5`!GiVWad*}N1C&@S4FphtiN#ugL_=Mn2i%cwceH`O z1D>#?fD)^IO}dgQU67MtFgz$~l>+EiEy53vQ;lZ2Gl0aVhna zE;&nCw1}s>Cg#-?ZP;r6BEwBjc5<7~fX{nD72W@kk+`}~uE8kF^uW=By1)QEzi{55`$IGUs9%z0Kf?!aDFYF^yY5RSw#^tDHE5`{ z(mwn^^tB7eJ>VG#>Wq!@dDacV(S=heS1k z1}JcV0{(|=fOzI?F2bU65`bnDW9VQ^FWBFLoiss-ov47K9c3h%uHY+6C0}GWcLg^OG^Ao2b(vacTrKvDp{= zRLoN&NnJ2=NVCeOewaR1(Wd z5EDuVT~v~Lw4MPQU683l#~Bi$+~T<<$h~h*9hgBW=2U#r!ZVH4L$>hl0O3>d5Pflf zk$A#&$`1YK;gINDU7$^AcmB_0-coi}iGiFkmoOV)q@yXAA@7k$EVX_~<{-*#&16QQ z>-%Pc5Pxz##fm7UFvMv-uTel^`b)HUo;i!ED?3;#3{yZA^ zFsfff+fTMlJ7gyoM%&NEq@2mc^nJq*^B&j}G|YxU#=yv>l}z0JBQQ&h$867l!XrqM z_63#izDkotMbxCzW^SWH0k>36t5CrS?eSNS|Uvk(O7vd8uxEjwN?~8+Jw$ zcE*@7@NGjA5nL7=OaN6H0p4K&NkX>Cm(!-M|9k}d&8~*qT_qvW*VMs);=9kav zOzjs*iOA25q}GEv0Y+TXK22Nl z+>4=)b8CyCZVcg&haPdgYY+}2?#o$0kIq(M>bK5!$9VAWDmDf=S?>*UGFS|9(%$t* zvN41xHNH`_+X&$1%LMqwDWfN>K<*41wL%3Wdqh=VU&|&OqwE`%hAQpDeO#ucRN+M7 z^tEWA$*`Lj>#Ca)Ydg7($O53qxt{}@-QC4KA~ulErrxFB>M)PfgrkS4*%v^_&}Eba znroH@!#0>QXc~gJ^*9>?k;`Pg(Xm~0On_dHG#=YI3%0+60~=t}fRZKOSe%D8csx?% zsv!Ac#!gv;uGHOWjW>2d4&bP>`~{ZqVOwn3m9mz>hFYM%iNumUKTXaua#IVG#4dp` zAzd;!I!(Q!X9&_-Y8FZ=7d9YgnoKZVOJYp%@Zh>0b&xWAH_C`ndV{Rpb-g_Oma}j| zq;a!#Qa`8lMhX<4qZwh=ASdO0=$nH|J^5`&wlai7+v_3&{^n;c=juf!dDqdfz@MOV zl+9VEFM6vpcx%b_Qi`~ZFcfNj*e`Jf|uc{Ld}WRFGOV((Kof+|D) z1H7_*3hR+wsi&eqI1q{3h#BotHBp2)eAsWAHkIc}okfyhufqx6)N;ptW8x~;E4ka5 zyjiUmm!#GqB+aDgm5Y#>V9N^4503%)4=nl`=lXaT5vO=(iriU0a5&mQ%}7)g=`6+-aXSJ^pR> z{QFNrtURTonz7xNIJM+(=CSoKmHHx!?XV`8AKPgII^HNs-(>0eukl89 zJOI#oad6@9iqPY}F~@7T#rUY^$F2E#BmFsn2(>5hfzNk85!zL2^&>5h{hMYxlKx4- z#12J~v@d>`nvXboC6x$pSEjt?r(>L`SICl<*mB;t)JQQ-bifA}+{b(TZ^Ln^ZB)Ky zO27mqKjY-;hw&`B=ErPGS0{%|t3`PCX&ZwcKPo2WFIY?#9RDHaTT26@j}8XYHhPYc zEx_c_pvNef^*DrlVP!thpCR|KiKv`>qo$hxVd|tv4!qe}tG+zt(DOW;QE7(tMH*8a zw9;%j>(m)>EYOX6Sr;dICKcdC&EFiz?efqhE>e&Uox3%ZFJwYV(A$aojshzI%0dmD z-2t5&Go(78@<>uRY^w!?d=D`c5JQxFqnN*%>!qouOD0Cur}4U`4!GlKR6!iRstdiQ?{Ta+HaJY04RNi(aNyX z5(&}@x;xu%wZ@@`lNPP*E3&6KV(u6>Ft$VTe(!A}EQ76dmBP`-#8c z3Y4@o!`#0t>@$b2tvUJ9X}0EJ-*1(iATZQ)3D$$*2tD# z5GaviwkdykDN*$DxYlHINxwNfo&}$55Hx>V)8G2CBoPB8LE$DDQyyEG@vlLMgqxm{ zV5yofLKoexuNDF@LlWZe#5WI&8ZHr(%mc)@T&MQz*9LDL`WwyNN?(N9(F?C94Ib|T zsGe#|&mKv#{GNiDe-OYudj=L6d@4r(GsJ3Aac^7Fw|N)pQK1QxR1OG{<}6^SEG~vX zx0>~|)dqJzl?AOWJ%LBje1HaX$n_LlDxiuO_7n$9>I{=70nT1#M*ALnW8nKJRmATp zbmh?}IXhYN-(Xkdrx5+=^VB-magyezY`yhvwTL2{UhsI-cmy+Z3fEc8<{jBVhz2&soXdZ&BeD$Gs{i3f=w5*( zm@Y3dHokx0#O1NKS=9H8&F#pIjdvP@{jlBo+q*xoG3K!`)~WtybO(&_B%#BF{CTzg zb^xE_l))Sto&M$98}1OQmI{=6y=x#OgZ6Q6?pGUQR(yl;eq2H=d{aWbo*<5eQ)bgx z#)CwoyN}EH7BeJTSw19MdNi1+)YC6y`aI^35o(7mzf!dScmHwUjM}}!p zoVarH_>$e}y>hYvS$Fz+XAM|NLKV<#c_%RQv~}p*?EWb86nyz$S^fNVCcj8MbD-@t z=R)BX@qb^ad)o*AEYvxg8Cx6wYa>7wFJXKM90-UI>-Q?^pKQOFf33b9Ys%T;a3Hn5 z+w;~qYK=BJBw;3otmEGxcSaGF4#h3hu}DOAX(XiLX+j^Y6!iUWJ|W|~`k8VOLel5s zr0yoWSSrXpES|kOjq-Pk{sAI716|US)b-8bGx)|P`)hsSR>NU%ee?cuouUVPc~FcP z)`L423I9m?$BZaScw}R$lRF36r{ZP;uTS8|1DF)^ppPm?SrG&>$;T?x#6J3@^p$Y= zXI5RVexx4TN@QDmU{B;VRjQ@zG|vam9F4SMJp(qKc^Ih?9 zx*tfeCW2xdWC83B22T{ z=W=7ErzoAnx!(D>uM1kB-GBYz*`!_bVG0NhtYR|l>wb0R+UhAAObPH00d9|5t=8j| zFC0&{<#wx<1>UgbLXEEv*j|i#!f13Y5ZiZs*lizet(^`rKKk2xIKZzJom?N#0l1jR z_8sAMtXb=uzs@8?L1#nCyEZEk)YQT3%Al!;XzEymLd$IDX~~R(_CW$E3WkzO@o|lv zfq^Tw>xd2}p`J#GR;o;8;f00m-YXK$22O`%KyeNl^|xmb%_GZ{m+L;=J@m4iUVqKc zkIcyAf7re{-<*;V*lnZj28|QXTQ5Fszk6I#Xl>8%yge9Hw`pNKZ-2d7ux-}=p1H86rX4NG@+S%0{qR_%a>s!0uF+Y5s)Slc+Dc(~h$aLr2 za56LxvYJM6&~}84T-cebceQ9d<8^(m%|x(F20dBz}wK0`W62WhnT}EJ6Ha z@P4>wMQCrH&E;LLn#E%^Tup3)wzHwtM2nmfwNk))TE6QrIVR_l6MiB!?MTUvWIfdV z6^d1U;?bzEfqCkj+zDVQLI#I-LXx%UsoCzU{Mluyw`Y~%0r0*B{!dWvX~O2lWxw}q z+XtXnKs+H0&WqV|?)rut!a^rUFdBap=n-zPva!=BkG{eoBsi%dm~b;7X(WB0I407Q z6mnE)&LJ+f(}f^~ojM=cizbccR-f$H8JW~7GVL+|D$SAih~KH!G=|~VoRvnNYwTM< z!E!RN%{E-}fH%4ireDfTc$Dywf|T!l%O%$8kaPdqW>2FVf?CgK)Dr>92|iXCTf=$u zL%M@j;dXViSMT!i)SHW?x$Rsuf9c|GJ+F<~-BY8@b9Z4%ydPY>LBg3G;H+7nfc$^R z>vG$<;SCww6*x1?>a7z;)P(mZKLrf9VrIk1pR(z4g@~?mqkQZGTgJYwn5yrZ(zNgC zdYaWNF2pgR#|IhQcCA&4=nfa!*)y?pi=|$%tcz|tr-!0k;vmwOHHn>fjxwWzP>s5J z#`fDG{HA`Rrcr}OOHXtARi(5N$ii6dXTVlxW6>tZfgXtXCu?D}AZi7-qIU~3gC42L zt7x*tAVp`&*#$nvc}t;(ecOdI+qupWvL8sp?5m~r2KMmD4bV2ebIQ}=PmVPmp-AyTl*IKO zT{6S=?klBC-^w5(*A#eRCt8h(j@OHJiCdQ2l9SyY&&1e`+%rx;f{-b5TeMa8 zPOIKtp0XJXtR*Zn`!FM$2y;3iR&yF{(+Nv0MJH^r)v&UIr64_D3bSZUyFn-9!vaa# zROinx+ye8ZYIJaN7`xJV=Fi<I-8fV;)&lu!7n~T{&Pod(7V}yA23#o z0>*;3tzy7f;9#b2Z*275(cav~)ZuL_##8e{Bu+iL7sL1~qvB!jFzPzkr{uq>DXd~{x{guG=5tp;K69NbQ6E-kW*b5qZ zVh2${yleNPE)DrEUb+~o@kOb!>h+O(0l02OT6?6$3H6a)mkSd08zklC#_IXLy z;%pKwqh2r7Q+eim^J*i<*)`Vc?VMcZ7=_fvEE6=U`a8mNxmM?uA2V2swFYyf;w^?Y zdMHS_sf^X|++bH!kB>?4r%1|+tJa(j{8ymRH};Nd21n(Ws%g3S%*W&vhVxejK!$3m zlWR2#kGPVDwL#(3?AKgyW=@`)u+~f~qqe0@hAbi{6y84`4O<^oVg=rM3Rs#naB3RE zK6(@j*YyqK>*g;Ir^j;9nw>N8yB4547+a4E&sx48hLI2liCvXXI3-}HUny|@_dXH`0AQdJi|txq-< z(1LR~pIG-mq+e2X5{f`*1IsDunyD;US_qQvdB}74*p+zwz6Sa#G#W$ymIPw~$)5mvq~pGx)qR zOlpO&K{6rJG%g|DKyGN?D%pBSF8pNXs?`i+0&3o2}>Y-x@zoPAu*W!(zv5oV-Cfi+Ej zDSl~wxxTr433@SpE%RP_?LT~7XkX@E<3IIY=0Em6(p}&ofJKJwU=D5kBurN$Yvt%mn||Ebl=@Vge((yH|2o~i<> zwMXpb0_AcH1W|!NbuEGdP49ud^mXktw8XMS!aiL0Xi(?L6&HClnXgfJzY)&=d;r`_ z7PN~583GOJ6Xk|_6-|pd^p3e|+hlEPr;W?cbcd4)$b+G9o$Q0!vf>lL7O)UQVJt-> z6p4ABXS8y@ccr;esL4OLLm9 zv;)zv-mZbJmGk+VK6$izo?LsUUai>(KwhoM;f{fw=!{Du?WEQ1Evk_>wc)xHdh4S= ztiynA+;S#CU5`zwopa0TO}qR-Z4!PjTk3EKFjJnH0bFT zUx>|Uo!i>YR54PR71lK90Ub8r{FKIzoaO#QlTZT_hJpvbWLsNx(tWuA4zrz*PXz}A@r=j$0sg6dLFX_#o14H(MfI=1loz-q2%a+-a=g%Fiy>{B0jTS_I=c%n1rv? z*F%|vDme|%kf(~-Tc5_FM8ddAOMuqv002}9wF_4Py-Nxr2=gSdhArtc&s z?)a7yhe$1zPjUTbrTkX*qr~ID zXaapN5K|RLG7gdp-azf1T7zqaplZg-4NQ_I4)$f0&VH(B=423)a+s1MrzQ5RDn(EL zJykn06UqoqtYbq%u-OOAx}A!vF6iYkTz2;&gbxlJD@%F$E;n{ES)!{k(CN&yDdgRWNQ0W&D&zsk%;ArSDqteW+V6-V=|jqW zj+HDbUj=aoUT%r>tVpdPDD0=TcQ^NnPWie08O8G!XUh5&FZX(1Q7+Io zIt4^ya{w*TglD;C1YpakVvjJtsQrfhc}Iw_b?qCJ=egK#he01ibn15_i71KSi0H;^ zmSPXDvAymqeVQ&2Rec!)$&JSqzX>kmVjs4%R~b;2owmLZG(hGoot?+GZjVo9+mQw| zB9hRAOGtQvhx_LL1pR&yU3PKBT%5&t#XPjkHx7a#?Bm!!Q?--~ax%k9GtI2G>FQ$< zM);rzGVHC+cB8vK?P|8bfBoRS{*JY1NgyJNP~6@0;tTh83HI7D^pE;D!6kP-1KGHU z^ZfnY5Xd`rojuC-!P06+~^gzJAS9rxJY89G!n*oSI14MA3YwujA?6-gLg$IRM z?5Ep?(#!~UE@d2t>fvrgM{~o?FKY;iry4(rAR`khhcX8nK;7?B3&bKc(>{ZuT*hxg ziN1TlG6Si%((wzLItum4=_m5VrvXFD3Umz)RN$OQtCQRH4ETurR6mgZEJwx8 zxZ5=7l&t!4p-9hckx>o8TFmQ1Tj|1?7-H3G9{odxg9!rnC(JiHJQ1#>0gG^s&((b& z3FOaild4~Tou&Ef5MJX!hTIn51QQY%5D?;D$6pL=Z7qMDdU>y8o63mfm09zuchAQZ z6-7pw10y$1&88Zkw|~RR^$Dz4k7NleIq&&)0clb`l{_Qj@oB|$&87coM;l|0N3s_T zv69D;5hNox?%Xgq)8$+*Gh@2`y){viT1Pc+FF>XDK?@=~URTxuL!>*Ec|Eg1vHgvCN;`?5`OIVfAo8K<#=!K=A*WfIGTb8ULDjujm{`E@_~@M)bVu<@zB8vwCf>FAT;d z4{K-@3Zv7}kP61fazkB&;>^*8R?joqg^tko~6M?97}4&6vZaF`{;4cSXoLE@Dk!Xc#Q zo~|+ug~zbMlnBk)xB9Norq5?j#;2Ei8M~vUHQZd2EFqBUF=4XFNC+`57paJ+lQi3g z)4Pkf1Fc>0w%dZAO$d~P1-4l`Ndy<1s;Ov}sXipIP$DCIc$UW}_Z)hiaMd_*eg1~d zY2EMShdNwLdd>5poB)A$&7wK$pwd<}ZJnvJ>D1A~cI(=2sH14(`m=n$yjj6Cb(`mq z&@7WQ&yv60+7Tp4;bu6bP<2j!IqAj7p^j@|9I5ht!W=l8jr3X+z31g5*?ry>_U9L& zjNwaoYaG9HI{Dn+8-HQEknb%n3m8StYa)nqql)GRh+E{GFR7E4gRO%Gkj zKJURsJjT;3#7~>vQ^fVoer=#=gFj4u@C;;*A8+Pa;&|>G%-AKp5Qclm-mHJpFUq@~Ptv8sEFcceJYc~-}!VwRU##NQDQIz*m zfeNXdxbFK^+j*}!Y>ho*iH@|*YAAd|wRd?tFZ#`z%yL*>va#w+xepD*mox$rdZ1wJ zCRP^~Aciz#mJ$c`1BtH zRp{rF(pdYF^bs^FYT#5X@=Rte2O3!ETC|{YRO#UCNfkff%VT~B1Q}U*XlofK%zQ6` z`bs;QgZ1)3=lElh+YhV_EOdYR^eT;dV<;A_aTHos80IfCMMLG9du3lhbX5v_yFgsH z#K&dqwK-03EwK+cI#biF_X;5E1Q^%-(fHRmv4qRbfec~L?9r8N~KwYcB4q6B4a{8BfT8Zqo20ogii?6r*$o*ka3uh=+rGo0EPGVUf z3ivEmMP*5&E+nG^mg&POGkE-{Al-^=9B?+^KCgLwz%fkb@UsLV!P46eP zKUAk;-CNqRka*MClrc1pz{ZMuj@X!NmG_Q>J=Hc~DS*%kr0A1-msWG;f zb)Kt4X!YIhG9>#R{6Z|Pq3JJHV?xF0Cstu5M1-4jQn>ey4G3L@H7+_9n_CJRlvRau?o3}xifS_2DhZ=bq)V^sm^wTPm)z_SQYYJHWN(s$YhdK zun%$y67UkIYVLfJjH!&IMwpyFw@tSd42uj-9+Pa0RZ<`0>N^WK!qG0eM4W`LAEu*1 z?1k)DRg!)NNnk%kxxyOssGtk2EmN0e`S)(o%nM-h;KNCk!i0+i{ulz!_TvU3!WKd- zLNl7Xrs`!qOH;P2MT3f@1@HTo;8)VdFO$pW7uCQL$E==o5?7;!$n2z~VwA!)p3ub3 zlYB(y?a`Nqm}d;?30p)u)!^IKtD-EX2Je8s_d$^?c@~7t87GU(Ok0r-D<~Vn7PMxI z8!F37Ja74fIkvKyCj zA@u2W^wRW}qW$jv-n~71paTdFi+_w)#`)&7KQ><=97>V;oBbJ4rl#LJ?<*;jm6 zp>%0!e}$6aNmf{DwkAwWiH&l8N4Q&K zlJ0bK??1SLiD!o8&jbqh75oQLjC*FEva4tZrmCp@!|uC$L_-vOR7O3tC|Q9fzUQgz z!RIx(lhtIeGfml{O<{EIP(gm7uM+puxVcn*?HBn;!$0dGRFe@5wBRltt>7V&XW8hvV6j`xb3uycq@Je*ZT++sT#01 za3}zaoG>TDH>ngWvU~7P1~kaj!We@p$nshmaFSP|P~bCy_6r7&y*=hNVIwkmUn;zC zHZT(~AP3;SR4m%E9Fv@YG9U% zve_>SN_yyL(B`(|$9iz{jsRhm0AWcpUy}Y5#xX-32R|QF8i&*fQVi51Tnt2$;EPmU zsP@guby)2W#(HW|n<7<89Q;PrFm3LuFJ+#$NheZ4{0Lr5x1(VTU&%N4&d=Qv!eVb5 zVPMPK3w)|@vI*ffesaEd-NlY@ya}Z{8aqp2t0+nm z1fs&?rZp?elnwe9K9I7G#TRF52|k(lGmd7sA$^501*wi=8q}&dgW0jwm@sMiTBBYJ zebdfMuxzEe&*l@!OO@vL zu{jSMoAVi)6X$U^11X(2hA+Sv+NAzpD9mC6MCo=btm!wRw&u@gnVc{(@bOCAt$v zyiO%r#W=O%#Y$z#J6@W$=Cv0##kq0e{yM$O>e%5HmK;NsQWBlAY&AA2I`~k~3RKAv za@9s3Uq_Ra2OU{3oIRK250dteqgT!$bcj|wB1z)HmIgvU-SdgT+_dH~OQ_0@DWl zg3(@@huMKIJU7pb=Yh~y+@5o^Oax`$X;cR!@umZ@#o`OXHeTKIc3=PZU1g}8G%x4Z(LtpO5yVE^Qyf8#8T8I$f|MCv>BJ4M=QlXF2wUT|a}K9V!?^huI^ z9VbVP(L8Qz6;h&|Zi0+VzTZh*^Dt`0St0z$lo!$B=cME(XglECrgY}vsZbCk3#|Fz!r(E$e}^}2k)AYK$3uCXIf#cU)_h`LMNu%5hfOS>OTduCpS{&a(dNg6 zcwZ*Iq8xAUDs`}XGlU)ImzH~5+oHqKpM1&LB4aExTPo4%PF7LqVg4T3^X*92Vh|8q zWA;w`L#Hm%K_#Uobns%@Uy|O3E^lkM+tDWXYs(Xal4XtD3rJ78DmH``lU&L3+H z|3O#IqMH%v%k7s{q2acK^aN$;Eh}lFrCC0osJ?^{I_QzB{`&GyM0SKZIJRK65UsZ( zl1nRNoWTsT(~#v^)Y3?MauuzoXdbNPE((Ofwe_E&@X=)@D~fGx>ufpAMiU3FqeY$1 zb2^y%O{oSsaoNy`zK^A|=O{TO6vis0`k%a^tCW`uIc=I@V2hs9>IpO<%S7>dinmzD zafdRz8=S!)D!E}k02(ZwkD%F^NzY6&Fm!%f+{cqX-sbRQNk^G>Xiksavg?x<32&)E zf<1q+CEQF3+!_(y0MSLrrUo&WO9bP^QU6T)KYw@^oNGCl0#;(+0Vg5ea>+i3*xEQ6 z+c@f~xP3Bq(0N;pDUBPF2Vp`Byd`hz&iTOd{*!)~zTUcVA?XI_^i2orRYHc}*-ZwO z9*B@{SgI8F@qPR2Q!AV}jb$jA==ADLiSD%qu>9xTl@b$z*u;wr^rV3IU9OO9A3&=n z&K@inH6c6vituJjq^Nj50Tvx;DlUL=M`S%~h$k3FU6JhRO*(AdTY2bPWqv9rYr(VQ z@^-4w%2H>jU%79R`U$D=+F;a`q=X=aB@joyZ*x5GQMQ3bSKVQo-}B)x@;}cGaNcq0 zs5=S&9-<}0gu&DbBg5WsVUO!6C?8nVt{O3aHC31(hz%=)tTJ9#A{g&WN<8l#?46q?$_4q z=vj!D6+sL>A$i9_pIzH_2O!NIu(P55`~2I>(TeUGs_P#x$D==Y>4XZS&hP6j=QWf4 zulVy%rT>mVZ*_hv?f$dQuO9P%DSPXZzppoCZ`a>)asR3B-`Tit%)j+f{Jq+La&!L; z(Z91z|Em23;L?98{Ui7E-_`$}NBLLv13<+1tNNc=mH*dEzoi8JzTRG153sNa2si&% zg@2-S$nm%M^zVlLJCMEU`Hd0^=ijRRkFfS{Ise|~{!0!o{x3QIW7GTJ68^nT_m_lL zs^1d+T($fEe|Km=1|$HiKMraA(?kA!OzSU=jDN58*P*R{H~HUd&3_3f0r(g|@84nj zzZ(6P)A{>)v#{@P3;!d-^PesMcaG;<-QQL#{U3Gz%J@{20sqxmkpcPBkO00>?zejX E54>4HdjJ3c literal 0 HcmV?d00001 diff --git a/public/excel/ZHENGZHOU NISSAN Z9_Leads_2025-12-04_2025-12-09.xlsx b/public/excel/ZHENGZHOU NISSAN Z9_Leads_2025-12-04_2025-12-09.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..751faa27a23007d6e8e89bda02636e88f452f050 GIT binary patch literal 14161 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 literal 0 HcmV?d00001 diff --git a/public/excel/jetour t2_Leads_2025-12-04_2025-12-09.xlsx b/public/excel/jetour t2_Leads_2025-12-04_2025-12-09.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..ef512a1c015357d701fb0ff531a8992cc2fc00f6 GIT binary patch literal 17480 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 literal 0 HcmV?d00001 diff --git a/public/excel/leopard 5_Leads_2025-12-04_2025-12-09.xlsx b/public/excel/leopard 5_Leads_2025-12-04_2025-12-09.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..d31c5e907ff948a66c953b2a2b1d9ddd6ad0e54c GIT binary patch literal 11468 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 P^g@t@dXcN5eAWAZ)oCZU literal 0 HcmV?d00001 diff --git a/webman b/webman new file mode 100755 index 0000000..3f55062 --- /dev/null +++ b/webman @@ -0,0 +1,71 @@ +#!/usr/bin/env php +load(); + } else { + Dotenv::createMutable(run_path())->load(); + } +} + +$appConfig = require $appConfigFile; +if ($timezone = $appConfig['default_timezone'] ?? '') { + date_default_timezone_set($timezone); +} + +if ($errorReporting = $appConfig['error_reporting'] ?? '') { + error_reporting($errorReporting); +} + +if (!in_array($argv[1] ?? '', ['start', 'restart', 'stop', 'status', 'reload', 'connections'])) { + require_once __DIR__ . '/support/bootstrap.php'; +} else { + if (class_exists('Support\App')) { + Support\App::loadAllConfig(['route']); + } else { + Config::reload(config_path(), ['route', 'container']); + } +} + +$cli = new Command(); +$cli->setName('webman cli'); +$cli->installInternalCommands(); +if (is_dir($command_path = Util::guessPath(app_path(), '/command', true))) { + $cli->installCommands($command_path); +} + +foreach (config('plugin', []) as $firm => $projects) { + if (isset($projects['app'])) { + foreach (['', '/app'] as $app) { + if ($command_str = Util::guessPath(base_path() . "/plugin/$firm{$app}", 'command')) { + $command_path = base_path() . "/plugin/$firm{$app}/$command_str"; + $cli->installCommands($command_path, "plugin\\$firm" . str_replace('/', '\\', $app) . "\\$command_str"); + } + } + } + foreach ($projects as $name => $project) { + if (!is_array($project)) { + continue; + } + $project['command'] ??= []; + array_walk($project['command'], [$cli, 'createCommandInstance']); + } +} + +$cli->run();