|
|
@@ -34,7 +34,7 @@ class ProductSurveillanceJobs implements ShouldQueue
|
|
|
public $timeout = 600; // 10分钟超时
|
|
|
|
|
|
protected $message_data;
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* Create a new job instance.
|
|
|
*
|
|
|
@@ -96,38 +96,64 @@ class ProductSurveillanceJobs implements ShouldQueue
|
|
|
$where[] = ['company_id', '=', $company_id];
|
|
|
$where[] = ['status', '=', 0];
|
|
|
$need_config_product_data = [];
|
|
|
- $config_product_data_info = $ProductModel->WhereRaw("FIND_IN_SET(?, sampling_cycle)", [$now_week])->select(['product_name', 'sampling_start_time', 'sampling_end_time'])->where($where)->get()->toArray();
|
|
|
+ $config_product_data_info = $ProductModel->WhereRaw("FIND_IN_SET(?, sampling_cycle)", [$now_week])->select(['product_name', 'platform', 'sampling_start_time', 'sampling_end_time'])->where($where)->get()->toArray();
|
|
|
if (empty($config_product_data_info)) {
|
|
|
$config_collect_product_content .= '无' . ';';
|
|
|
//没有采集任务不处理
|
|
|
return true;
|
|
|
} else {
|
|
|
- $config_collect_product_list = [];
|
|
|
- foreach ($config_product_data_info as $product_name) {
|
|
|
- $sampling_start_time = $product_name['sampling_start_time'];
|
|
|
- $sampling_end_time = $product_name['sampling_end_time'];
|
|
|
+ //实际采集到的所有商品
|
|
|
+ $where = [];
|
|
|
+ $where[] = ['insert_time', '>=', $start_time_string];
|
|
|
+ $where[] = ['insert_time', '<=', $end_time_string];
|
|
|
+ $where[] = ['enterprise_id', '=', $company_id];
|
|
|
+ $scrape_data_list = $ScrapeDataModel->where($where)->get()->toarray();
|
|
|
+
|
|
|
+ foreach ($config_product_data_info as $product_data) {
|
|
|
+ $sampling_start_time = $product_data['sampling_start_time'];
|
|
|
+ $sampling_end_time = $product_data['sampling_end_time'];
|
|
|
+ $platform_id_data = explode(',', $product_data['platform']);
|
|
|
if ($sampling_start_time != '' && $sampling_end_time != '' && ($current_time < $sampling_start_time || $current_time > $sampling_end_time)) {
|
|
|
continue; //如果当前时间小于采集开始时间或者大于采集结束时间则跳过
|
|
|
}
|
|
|
- $need_config_product_data[$product_name['product_name']] = $product_name;
|
|
|
+ if (isset($need_config_product_data[$product_data['product_name']])) {
|
|
|
+ $platform_id_data_merge = array_merge($need_config_product_data[$product_data['product_name']], $platform_id_data);
|
|
|
+ $platform_id_data_merge = array_unique($platform_id_data_merge);
|
|
|
+ $need_config_product_data[$product_data['product_name']] = $platform_id_data_merge;
|
|
|
+ } else {
|
|
|
+ $need_config_product_data[$product_data['product_name']] = $platform_id_data;
|
|
|
+ }
|
|
|
}
|
|
|
if (empty($need_config_product_data)) {
|
|
|
return true; //没有采集任务不处理
|
|
|
}
|
|
|
- foreach ($need_config_product_data as $product_name) {
|
|
|
- $config_collect_product_content .= $product_name['product_name'] . ';';
|
|
|
- //实际采集到的商品
|
|
|
- $where = [];
|
|
|
- $where[] = ['insert_time', '>=', $start_time_string];
|
|
|
- $where[] = ['insert_time', '<=', $end_time_string];
|
|
|
- $where[] = ['enterprise_id', '=', $company_id];
|
|
|
- $where[] = ['product_name', 'like', '%' . $product_name['product_name'] . '%']; // 增加模糊匹配
|
|
|
- $actual_product_data_count = $ScrapeDataModel->where($where)->count();
|
|
|
- if ($actual_product_data_count < 1) {
|
|
|
- $actual_collect_product_content .= '无' . ';';
|
|
|
- } else {
|
|
|
- $actual_collect_product_content .= $product_name['product_name'] . ':数量' . $actual_product_data_count . ';';
|
|
|
+ //更新平台名称
|
|
|
+ foreach ($need_config_product_data as $product_name => $platform_id_data) {
|
|
|
+ $platform_name_list = '';
|
|
|
+ $platform_product_name_sting = '';
|
|
|
+ foreach ($platform_id_data as $platform_id) {
|
|
|
+ $platform_name = $this->platform($platform_id);
|
|
|
+ //实际采集到的商品
|
|
|
+ $where = [];
|
|
|
+ $where[] = ['insert_time', '>=', $start_time_string];
|
|
|
+ $where[] = ['insert_time', '<=', $end_time_string];
|
|
|
+ $where[] = ['enterprise_id', '=', $company_id];
|
|
|
+ $where[] = ['platform_id', '=', $platform_id];
|
|
|
+ $where[] = ['product_name', 'like', '%' . $product_name . '%']; // 增加模糊匹配
|
|
|
+ $actual_product_data_count = 0;
|
|
|
+ if (!empty($scrape_data_list)) {
|
|
|
+ foreach ($scrape_data_list as $scrape_data) {
|
|
|
+ if ($scrape_data['platform_id'] == $platform_id && strpos($scrape_data['product_name'], $product_name) !== false) {
|
|
|
+ $actual_product_data_count++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ $platform_product_name_sting .= '【' . $platform_name . '】' . ':' . $actual_product_data_count . '条';
|
|
|
+ $platform_name_list .= $platform_name . '/';
|
|
|
}
|
|
|
+ $actual_collect_product_content .= $product_name . $platform_product_name_sting . ';';
|
|
|
+ $product_name_sting = $product_name . '【' . $platform_name_list . '】';
|
|
|
+ $config_collect_product_content .= $product_name_sting . ';';
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -139,20 +165,24 @@ class ProductSurveillanceJobs implements ShouldQueue
|
|
|
if (empty($config_low_product_data_info)) {
|
|
|
$config_low_product_content .= '无' . ';';
|
|
|
} else {
|
|
|
+ //实际清洗出来的低价商品
|
|
|
+ $where = [];
|
|
|
+ $where[] = ['insert_time', '>=', strtotime($start_time_string)];
|
|
|
+ $where[] = ['insert_time', '<=', strtotime($end_time_string)];
|
|
|
+ $where[] = ['company_id', '=', $company_id];
|
|
|
+ $process_low_priceGoods = $ProcessLowPriceGoodsModel->where($where)->get()->toarray();
|
|
|
+
|
|
|
foreach ($config_low_product_data_info as $product_name) {
|
|
|
$config_low_product_content .= $product_name['product_name'] . ';';
|
|
|
- //实际清洗出来的低价商品
|
|
|
- $where = [];
|
|
|
- $where[] = ['insert_time', '>=', strtotime($start_time_string)];
|
|
|
- $where[] = ['insert_time', '<=', strtotime($end_time_string)];
|
|
|
- $where[] = ['company_id', '=', $company_id];
|
|
|
- $where[] = ['product_name', 'like', '%' . $product_name['product_name'] . '%']; // 增加模糊匹配
|
|
|
- $cleaned_product_data_count = $ProcessLowPriceGoodsModel->where($where)->count();
|
|
|
- if ($cleaned_product_data_count < 1) {
|
|
|
- $cleaned_low_product_content .= '无' . ';';
|
|
|
- } else {
|
|
|
- $cleaned_low_product_content .= $product_name['product_name'] . ':数量' . $cleaned_product_data_count . ';';
|
|
|
+ $cleaned_product_data_count = 0;
|
|
|
+ if (!empty($process_low_priceGoods)) {
|
|
|
+ foreach ($process_low_priceGoods as $process_low_priceGood) {
|
|
|
+ if (strpos($process_low_priceGood['product_name'], $product_name['product_name']) !== false) {
|
|
|
+ $cleaned_product_data_count++;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
+ $cleaned_low_product_content .= $product_name['product_name'] . ':数量' . $cleaned_product_data_count . '条;';
|
|
|
}
|
|
|
}
|
|
|
//配置的违规清洗商品
|
|
|
@@ -163,19 +193,22 @@ class ProductSurveillanceJobs implements ShouldQueue
|
|
|
if (empty($config_violation_product_data_info)) {
|
|
|
$config_violation_product_content .= '无' . ';';
|
|
|
} else {
|
|
|
+ //实际清洗出来的违规商品
|
|
|
+ $where = [];
|
|
|
+ $where[] = ['insert_time', '>=', strtotime($start_time_string)];
|
|
|
+ $where[] = ['insert_time', '<=', strtotime($end_time_string)];
|
|
|
+ $where[] = ['company_id', '=', $company_id];
|
|
|
+ $process_violation_products = $ProcessViolationProductModel->where($where)->get()->toarray();
|
|
|
foreach ($config_violation_product_data_info as $product_name) {
|
|
|
$config_violation_product_content .= $product_name['product_name'] . ';';
|
|
|
- //实际清洗出来的违规商品
|
|
|
- $where = [];
|
|
|
- $where[] = ['insert_time', '>=', strtotime($start_time_string)];
|
|
|
- $where[] = ['insert_time', '<=', strtotime($end_time_string)];
|
|
|
- $where[] = ['company_id', '=', $company_id];
|
|
|
- $where[] = ['product_name', 'like', '%' . $product_name['product_name'] . '%']; // 增加模糊匹配
|
|
|
- $cleaned_product_data_count = $ProcessViolationProductModel->where($where)->count();
|
|
|
- if ($cleaned_product_data_count < 1) {
|
|
|
- $cleaned_violation_product_content .= '无' . ';';
|
|
|
- } else {
|
|
|
- $cleaned_violation_product_content .= $product_name['product_name'] . ':数量' . $cleaned_product_data_count . ';';
|
|
|
+ $cleaned_product_data_count = 0;
|
|
|
+ if (!empty($process_violation_products)) {
|
|
|
+ foreach ($process_violation_products as $process_violation_product) {
|
|
|
+ if (strpos($process_violation_product['product_name'], $product_name['product_name']) !== false) {
|
|
|
+ $cleaned_product_data_count++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ $cleaned_violation_product_content .= $product_name['product_name'] . ':数量' . $cleaned_product_data_count . '条;';
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -187,20 +220,23 @@ class ProductSurveillanceJobs implements ShouldQueue
|
|
|
if (empty($config_violation_store_data_info)) {
|
|
|
$config_violation_store_content .= '无' . ';';
|
|
|
} else {
|
|
|
+ //实际清洗出来的违规店铺
|
|
|
+ $where = [];
|
|
|
+ $where[] = ['insert_time', '>=', strtotime($start_time_string)];
|
|
|
+ $where[] = ['insert_time', '<=', strtotime($end_time_string)];
|
|
|
+ $where[] = ['company_id', '=', $company_id];
|
|
|
+ $process_violation_store = $ProcessViolationStoreModel->where($where)->get()->toarray();
|
|
|
foreach ($config_violation_store_data_info as $store_name) {
|
|
|
$config_violation_store_content .= $store_name['store_name'] . ';';
|
|
|
- //实际清洗出来的违规店铺
|
|
|
- $where = [];
|
|
|
- $where[] = ['insert_time', '>=', strtotime($start_time_string)];
|
|
|
- $where[] = ['insert_time', '<=', strtotime($end_time_string)];
|
|
|
- $where[] = ['company_id', '=', $company_id];
|
|
|
- $where[] = ['store_name', 'like', '%' . $store_name['store_name'] . '%']; // 增加模糊匹配
|
|
|
- $cleaned_store_data_count = $ProcessViolationStoreModel->where($where)->count();
|
|
|
- if ($cleaned_store_data_count < 1) {
|
|
|
- $cleaned_violation_store_content .= '无' . ';';
|
|
|
- } else {
|
|
|
- $cleaned_violation_store_content .= $store_name['store_name'] . ':数量' . $cleaned_store_data_count . ';';
|
|
|
+ $cleaned_store_data_count = 0;
|
|
|
+ if (!empty($process_violation_store)) {
|
|
|
+ foreach ($process_violation_store as $process_violation_store) {
|
|
|
+ if (strpos($process_violation_store['store_name'], $store_name['store_name']) !== false) {
|
|
|
+ $cleaned_store_data_count++;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
+ $cleaned_violation_store_content .= $store_name['store_name'] . ':数量' . $cleaned_store_data_count . '条;';
|
|
|
}
|
|
|
}
|
|
|
//合并展示内容
|
|
|
@@ -219,7 +255,7 @@ class ProductSurveillanceJobs implements ShouldQueue
|
|
|
$start_time_string,
|
|
|
$end_time_string
|
|
|
);
|
|
|
- // echo $email_content_html;exit;
|
|
|
+ // echo $email_content_html;
|
|
|
//发送预警通知
|
|
|
foreach ($email_notice_list as $email_notice) {
|
|
|
$message_data = [
|
|
|
@@ -234,6 +270,41 @@ class ProductSurveillanceJobs implements ShouldQueue
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * platform 平台ID定义
|
|
|
+ *
|
|
|
+ */
|
|
|
+ private function platform($platform_id)
|
|
|
+ {
|
|
|
+ //平台0=全部,1=淘宝,2=京东,3=拼多多,4=美团,5=药师帮,6=1药城,7=药久久,8=药易购,9=药帮忙,10=熊猫药药11=药房网
|
|
|
+ switch ($platform_id) {
|
|
|
+ case 1:
|
|
|
+ return '淘宝';
|
|
|
+ case 2:
|
|
|
+ return '京东';
|
|
|
+ case 3:
|
|
|
+ return '拼多多';
|
|
|
+ case 4:
|
|
|
+ return '美团';
|
|
|
+ case 5:
|
|
|
+ return '药师帮';
|
|
|
+ case 6:
|
|
|
+ return '1药城';
|
|
|
+ case 7:
|
|
|
+ return '药久久';
|
|
|
+ case 8:
|
|
|
+ return '药易购';
|
|
|
+ case 9:
|
|
|
+ return '药帮忙';
|
|
|
+ case 10:
|
|
|
+ return '熊猫药药';
|
|
|
+ case 11:
|
|
|
+ return '药房网';
|
|
|
+ default:
|
|
|
+ return '';
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 构建美观的邮件HTML内容(内联样式版本)
|
|
|
*/
|
|
|
@@ -256,7 +327,7 @@ class ProductSurveillanceJobs implements ShouldQueue
|
|
|
<meta charset="UTF-8">
|
|
|
</head>
|
|
|
<body style="font-family: \'Microsoft YaHei\', Arial, sans-serif; background-color: #f5f7fa; margin: 0; padding: 20px;">
|
|
|
- <div style="max-width: 800px; margin: 0 auto; background-color: #ffffff; border-radius: 12px; overflow: hidden;">
|
|
|
+ <div style="mix-width: 800px; width: 96%; margin: 0 auto; background-color: #ffffff; border-radius: 12px; overflow: hidden;">
|
|
|
<div style="background: #667eea; color: white; padding: 30px 20px; text-align: center;">
|
|
|
<h1 style="margin: 0; font-size: 24px; font-weight: 600;">数据监控报告</h1>
|
|
|
<p style="margin: 10px 0 0; opacity: 0.9; font-size: 14px;">' . $start_time_string . ' - ' . $end_time_string . ' 采集与清洗情况通知</p>
|
|
|
@@ -290,7 +361,7 @@ class ProductSurveillanceJobs implements ShouldQueue
|
|
|
private function buildSectionInline($title, $content, $color)
|
|
|
{
|
|
|
$formattedContent = $this->formatContentInline($content);
|
|
|
-
|
|
|
+
|
|
|
return '
|
|
|
<div style="margin-bottom: 25px; border-left: 4px solid ' . $color . '; padding: 12px 20px; background-color: #f8f9fc; border-radius: 8px;">
|
|
|
<div style="font-size: 16px; font-weight: 600; margin-bottom: 12px;">
|
|
|
@@ -311,7 +382,7 @@ class ProductSurveillanceJobs implements ShouldQueue
|
|
|
if (empty($content) || trim($content) === ';' || trim($content) === '无;') {
|
|
|
return '<span style="color: #999; font-style: italic;">📭 暂无数据</span>';
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 检查是否包含"无;"的情况
|
|
|
if (strpos($content, '无;') !== false && strlen($content) <= 6) {
|
|
|
return '<span style="color: #999; font-style: italic;">📭 暂无数据</span>';
|
|
|
@@ -319,29 +390,21 @@ class ProductSurveillanceJobs implements ShouldQueue
|
|
|
|
|
|
// 移除末尾的分号
|
|
|
$content = rtrim($content, ';');
|
|
|
-
|
|
|
+
|
|
|
// 按分号分割
|
|
|
$items = explode(';', $content);
|
|
|
$html = '';
|
|
|
-
|
|
|
+
|
|
|
foreach ($items as $item) {
|
|
|
$item = trim($item);
|
|
|
if (empty($item)) continue;
|
|
|
-
|
|
|
+
|
|
|
// 跳过"无"项
|
|
|
if ($item === '无') continue;
|
|
|
-
|
|
|
- // 检查是否包含数量信息(格式:商品名:数量N)
|
|
|
- if (preg_match('/^(.+):数量(\d+)$/u', $item, $matches)) {
|
|
|
- $productName = trim($matches[1]);
|
|
|
- $count = $matches[2];
|
|
|
- $html .= '<span style="display: inline-block; background: #e8ecf1; padding: 4px 12px; border-radius: 20px; margin: 4px 6px 4px 0; font-size: 13px;"><strong style="color: #667eea;">' . htmlspecialchars($productName) . '</strong> <strong style="font-weight: 700; color: #667eea; font-size: 16px;">' . $count . '</strong> 件</span>';
|
|
|
- } else {
|
|
|
- // 普通商品名
|
|
|
- $html .= '<span style="display: inline-block; background: #e8ecf1; padding: 4px 12px; border-radius: 20px; margin: 4px 6px 4px 0; font-size: 13px;">' . htmlspecialchars($item) . '</span>';
|
|
|
- }
|
|
|
+ // 普通商品名
|
|
|
+ $html .= '<span style="display: inline-block; background: #e8ecf1; padding: 4px 12px; border-radius: 20px; margin: 4px 6px 4px 0; font-size: 13px;">' . htmlspecialchars($item) . '</span>';
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
return $html ?: '<span style="color: #999; font-style: italic;">📭 暂无数据</span>';
|
|
|
}
|
|
|
|
|
|
@@ -349,4 +412,4 @@ class ProductSurveillanceJobs implements ShouldQueue
|
|
|
{
|
|
|
Log::info('job_error', '低价商品数据数据-监控采集清洗情况队列完全失败', ['data' => $this->message_data, 'error' => $exception->getMessage()]);
|
|
|
}
|
|
|
-}
|
|
|
+}
|