From 7ecbb660d52288110cfc234397f4c58b0662c140 Mon Sep 17 00:00:00 2001
From: "WIN-C27C5MSVTPO\\16961" <1696136552@qq.com>
Date: Thu, 29 Jan 2026 11:34:32 +0800
Subject: [PATCH] =?UTF-8?q?=E6=8E=A8=E9=80=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/common/service/WordpressSiteService.php | 332 ++++++++------------
app/process/Task.php | 25 ++
2 files changed, 159 insertions(+), 198 deletions(-)
diff --git a/app/common/service/WordpressSiteService.php b/app/common/service/WordpressSiteService.php
index 662602f..b091057 100644
--- a/app/common/service/WordpressSiteService.php
+++ b/app/common/service/WordpressSiteService.php
@@ -98,9 +98,10 @@ class WordpressSiteService
$images = [];
foreach ($ucImages as $ucImage) {
$image = $this->uploadImageToWp($domain, $site['api_user'], $site['api_secret'], $ucImage);
- $images[] = ['id' => $image['id']];
+// $images[] = ['id' => $image['id']];
+ $images[] = $image['id'];
}
- $images = array_merge([$images[0]], $images);
+ //$images = array_merge([$images[0]], $images);
//车辆详细信息
/*$detils= $this->drawDetils($row);
@@ -130,7 +131,9 @@ class WordpressSiteService
$condition_desc_locale = $spark->chat("将下列车况描述翻译为".$locale.":".$condition_desc_locale);
$data = [
- "name" => $car_name_locale,
+ "title" => $car_name_locale,
+ "Content" => '',
+ "excerpt" => '',
"type" => "simple", //单品,不走规格变体
"regular_price" => number_format(($row['price']*$site['exchange_rate']), 2),
"sku" => "",
@@ -140,94 +143,82 @@ class WordpressSiteService
// "categories" => [
// ["id" => 16],//used二手车
// ],
- "images" => $images,
+ //"images" => $images,
+ "status" => 'publish', //发布状态
];
- $data['categories'][] = ["id" => $site['categories']];
+ //$data['categories'][] = ["id" => $site['categories']];
+ $data['product_cat'] = explode(',', $site['categories']);
//车辆档案相关参数
- $meta = $this->drawMeta($row['used_detail']);
+ $meta = $this->drawMeta($row);
//车身颜色
$color = '';
- foreach ($meta as $item){
- if (!empty($item['key']) && $item['key'] == 'color') {
- $color = $item['value'];
- $color = $this->sparkTransl($spark,$color,$locale);
+ foreach ($meta as $key => $item){
+ if (!empty($item['key']) && ($item['key'] == 'body_color' || $item['key'] == 'source_place')) {
+ $goal = $this->sparkTransl($spark,$item['value'],$locale);
+ $meta[$key]['value'] = $goal;
+
+ $color = $item['key'] == 'body_color'?$goal:'';
}
}
if ($site['tpl_type'] == 2) {
$meta = [];
}
- //$configDetail = json_decode($row['config_detail'], true);
-
- //车身级别
- /*$body_style = '';
- foreach ($configDetail[0]['items'] as $item){
- if (!empty($item['key']) && $item['key'] == 'jb') {
- $body_style = $item['value'];
- $body_style = $this->sparkTransl($spark,$body_style,$locale);
- }
- }*/
-
- //产品设置相关参数
- $meta[] = [
- 'key' => 'pro-intro-txt',//产品参数简介
- 'value' => "
- - Engine Size{$row['displacement']}
- - Engine Power{$row['power']}
- - Mileage(KM){$row['mileage']}
- - Color{$color}
-
",
- ];
-// Engine Size
-//Engine Power
-//Mileage
-//Color
-// Year{$row['year']}
-// Body Style{$body_style}
-
//属性:品牌、车体类型、颜色
- $brand_locale = $spark->chat('将车辆品牌翻译为'.$locale.':'.$row['brand_name'],null,[],'wpSend');
- $data['attributes'][] = [ //品牌
- "id" => "1",
- "visible" => true,
- "variation" => false,
- "options" => [$brand_locale]
- ];
- /*$data['attributes'][] = [ //车体类型
- "id" => "2",
- "visible" => true,
- "variation" => false,
- "options" => [$body_style]
- ];*/
- $data['attributes'][] = [ //颜色
- "id" => "4",
- "visible" => true,
- "variation" => false,
- "options" => [$color]
- ];
-
- // 构建车辆简介描述
+ $brand = $row['crawl_brand']?:$row['product_name'];
+ $brand_locale = $spark->chat('将车辆品牌翻译为'.$locale.':'.$brand,null,[],'wpSend');
+
+ //查询品牌id
+ $brand_id = $this->get_or_create_brand_id($site,$domain, $brand_locale);
+ $data['pa_brand'] = [$brand_id];
+
+ //查询车身类型
+ $bodys = $this->get_body($site,$domain);
+ $bady_style = array_column($bodys, 'name');
+
+ $style = $spark->chat('根据给出的信息判断车身类型(不要回答多余的文字,只需要返回车身类型,无法判断则返回:Other),车身类型有:'.implode('、',$bady_style).',车辆数据为:'.json_encode($row->toArray(),JSON_UNESCAPED_UNICODE),null,[],'wpSend');
+ if(!in_array($style,$bady_style)){
+ $style = 'Other';
+ }
+ $style_id = 0;
+ foreach ($bodys as $key => $item){
+ if ($item['name'] == $style) {
+ $style_id = $item['id'];
+ }
+ }
+ $data['pa_body-style'] = [$style_id];
+
+ // 翻译车况简介
// $baseInfo = $this->parseCarConfigDetail($row['format_car_info']);
-// $vehicleDescription = $this->buildVehicleDescription($row, $baseInfo, $meta, $configDetail);
+ $conditionDesc_locale = $spark->chat('将车况描述翻译为'.$locale.':'.$row['condition_desc'],null,[],'wpSend');
//翻译车辆简介描述
- $desc = "车辆名称:{$car_name},车辆参数:".json_encode($meta)."车辆简介:{$row['condition_desc']}";
- $vehicleDescription_locale = $spark->chat('根据给出的信息生成'.$locale.'车辆简介描述:'.$desc,null,[],'wpSend');
+ $desc = "车辆名称:{$car_name},车辆参数:".json_encode($meta);
+ $vehicleDescription_locale = $spark->chat('根据给出的信息生成'.$locale.'车辆简介描述(要求简短):'.$desc,null,[],'wpSend');
$meta[] = [
- 'key' => 'pro-intro-des',//产品简介
+ 'key' => 'pro-intro-des',//车况介绍
'value' => $vehicleDescription_locale,
];
+ $meta[] = [
+ 'key' => 'condition_desc',//产品简介
+ 'value' => $conditionDesc_locale,
+ ];
+
// $meta[] = [ //列表标签
// 'key' => 'hotpro_mark',//自定义热门产品标签
// 'value' => 'In Stock', //In Stock、HOT SALE
// ];
-
- $data['meta_data'] = array_values($meta);
+ //$data['meta'] = array_values($meta);
+ foreach ($meta as $item){
+ $data['acf'][$item['key']] = $item['value'];
+ }
+ $data['featured_media'] = $images[0];
+ $data['acf']['product_gallery'] = $images;
try {
$response = $client->post($url, [
@@ -253,11 +244,12 @@ class WordpressSiteService
$site->last_uid = $id;
$site->save();
- return $result;
+ $data ['result'] = $result;
+ return $data;
+ //return $result;
} catch (\Exception $e) {
$his = WordpressUsedCar::where('wp_site_id', $site['id'])->where('used_car_id', $id)->first();
- var_dump($his);
if ($his){
$his->retry_count = $his->retry_count + 1;
$his->save();
@@ -500,138 +492,81 @@ class WordpressSiteService
}
/**
- * 构建车辆简介描述
- *
- * @param array $row 车辆基本信息
- * @param array $baseInfo 车辆配置信息
- * @param array $meta meta_data数组
- * @param array $configDetail 配置详情
- * @return string
+ * 查询wp车身类型
+ * @param $brand_name
+ * @return mixed
+ * @throws \GuzzleHttp\Exception\GuzzleException
*/
- public function buildVehicleDescription($row, $baseInfo, $meta, $configDetail): string
- {
- $parts = [];
-
- // 1. 品牌 + 系列 + 年份 + 车型名称
- $brandName = trim($row['brand_name'] ?? '');
- $seriesName = trim($row['series_name'] ?? '');
- $year = trim($row['year'] ?? '');
- $carName = trim($row['car_name'] ?? '');
-
- $modelParts = [];
- if ($brandName) $modelParts[] = $brandName;
- if ($seriesName) $modelParts[] = $seriesName;
- if ($year) $modelParts[] = $year;
-
- // 尝试从car_name中提取版本信息(如 "Champion Edition", "Champion PRO")
- $version = '';
- $carNameWithoutVersion = $carName;
- if ($carName) {
- // 如果car_name包含版本信息,提取出来
- if (preg_match('/\s+([A-Z][a-zA-Z\s]+(?:Edition|PRO|PLUS|MAX|PRO|Limited))$/i', $carName, $matches)) {
- $version = trim($matches[1]);
- $carNameWithoutVersion = trim(str_replace($version, '', $carName));
- }
- $modelParts[] = $carNameWithoutVersion;
- if ($version) {
- $modelParts[] = $version;
- }
- }
-
- // 2. 引擎和变速箱信息(优先从 config_detail 中获取)
- $engine = $this->getConfigValue($configDetail, ['fdj', 'engine', 'engine_description', '发动机'], '');
- if (empty($engine)) {
- $engine = $this->value($baseInfo, 'engine_description', '');
- }
-
- $transmission = $this->getConfigValue($configDetail, ['bsx', 'gearbox', 'gearbox_description', 'transmission', '变速箱'], '');
- if (empty($transmission)) {
- $transmission = $this->value($baseInfo, 'gearbox_description', '');
- }
-
- if ($engine || $transmission) {
- $engineParts = [];
- if ($engine && $engine !== '–') $engineParts[] = $engine;
- if ($transmission && $transmission !== '–') $engineParts[] = $transmission;
- if (!empty($engineParts)) {
- $modelParts[] = implode(' ', $engineParts);
- }
- }
-
- if (!empty($modelParts)) {
- $parts[] = implode(' ', $modelParts);
- }
-
- // 3. 座位数(优先从 config_detail 中获取)
- $seatCount = $this->getConfigValue($configDetail, ['zws', 'seat_count', 'seat', 'seats', '座位数'], '');
- if (empty($seatCount) || $seatCount === '–') {
- $seatCount = $this->value($baseInfo, 'seat_count', '');
- }
- if ($seatCount && $seatCount !== '–' && is_numeric($seatCount)) {
- $parts[] = "{$seatCount}-seater";
- }
-
- // 4. 外观颜色(优先从 config_detail 中获取)
- $exteriorColor = $this->getConfigValue($configDetail, ['cys', 'body_color', 'color', 'exterior_color', '车身颜色'], '');
- // 如果 config_detail 中没有,尝试从 baseInfo 中获取
- if (empty($exteriorColor) || $exteriorColor === '–') {
- $exteriorColor = $this->value($baseInfo, 'body_color', '');
- }
- // 如果 baseInfo 中也没有,尝试从 meta 中获取
- if (empty($exteriorColor) || $exteriorColor === '–') {
- foreach ($meta as $item) {
- if (!empty($item['key']) && $item['key'] == 'color') {
- $exteriorColor = $item['value'] ?? '';
- break;
- }
- }
- }
-
- if ($exteriorColor && $exteriorColor !== '–') {
- // 翻译颜色为英文(如果必要)
- $exteriorColorEn = $this->translateColorToEnglish($exteriorColor);
- $parts[] = "{$exteriorColorEn} exterior";
- }
-
- // 5. 内饰颜色(尝试从config_detail中查找)
- $interiorColor = $this->getInteriorColor($configDetail, $baseInfo);
- if ($interiorColor && trim($interiorColor) !== '') {
- $interiorColorEn = $this->translateColorToEnglish($interiorColor);
- // 如果翻译后仍然是原始的中文值(说明未找到映射),使用light-colored作为默认值
- if ($interiorColorEn === mb_strtolower($interiorColor, 'UTF-8') && !preg_match('/^[a-z\s-]+$/i', $interiorColor)) {
- $interiorColorEn = 'light-colored';
- }
- if ($interiorColorEn) {
- $parts[] = "{$interiorColorEn} interior";
- }
- }
-
- // 6. 使用时间(从上牌时间计算)
- $licenseDate = '';
- foreach ($meta as $item) {
- if (!empty($item['key']) && $item['key'] == 'license_date') {
- $licenseDate = $item['value'] ?? '';
- break;
- }
- }
-
- if ($licenseDate) {
- $usageTime = $this->calculateUsageTime($licenseDate);
- if ($usageTime) {
- $parts[] = "used for {$usageTime}";
- }
- }
-
- // 7. 行驶里程
- $mileage = $row['usage_mileage'] ?? '';
- if ($mileage && is_numeric($mileage)) {
- $formattedMileage = number_format((float)$mileage, 0, '.', ',');
- $parts[] = "traveled {$formattedMileage} kilometers";
- }
-
- return implode(', ', $parts) . '.';
+ function get_body($site,$domain) {
+ $client = new Client([
+ 'base_uri' => $domain . '/wp-json/wp/v2/',
+ RequestOptions::AUTH => [$site['api_user'], $site['api_secret']],
+// 'auth' => ['your_username', 'your_password'], // 或者使用应用密码
+ RequestOptions::VERIFY => false, // 禁用 SSL 验证
+ ]);
+
+ // 查询车身类型
+ $response = $client->get('pa_body-style');
+
+ $bodys = json_decode($response->getBody(), true);
+
+ // 返回车身类型
+ return $bodys;
}
-
+
+ /**
+ * 查询wp品牌id
+ * @param $brand_name
+ * @return mixed
+ * @throws \GuzzleHttp\Exception\GuzzleException
+ */
+ function get_or_create_brand_id($site,$domain, $brand_name) {
+ if(empty($brand_name)){
+ return 0;
+ }
+ $client = new Client([
+ 'base_uri' => $domain . '/wp-json/wp/v2/',
+ RequestOptions::AUTH => [$site['api_user'], $site['api_secret']],
+// 'auth' => ['your_username', 'your_password'], // 或者使用应用密码
+ RequestOptions::VERIFY => false, // 禁用 SSL 验证
+ ]);
+
+ // 生成slug
+ $slug = $this->generate_slug($brand_name);
+
+ // 查询品牌是否已存在
+ $response = $client->get('pa_brand', [
+ 'query' => [
+ 'slug' => $slug // 用品牌名称生成slug查询
+ ]
+ ]);
+
+ $brands = json_decode($response->getBody(), true);
+
+ // 如果品牌存在,返回ID
+ if (!empty($brands)) {
+ return $brands[0]['id']; // 返回第一个匹配的品牌ID
+ }
+
+ // 品牌不存在,先创建
+ $response = $client->post('pa_brand', [
+ 'json' => [
+ 'name' => $brand_name,
+ 'slug' => $slug
+ ]
+ ]);
+
+ $brand = json_decode($response->getBody(), true);
+
+ // 返回创建的品牌ID
+ return $brand['id'];
+ }
+
+ function generate_slug($brand_name) {
+ // 将品牌名称转成小写并替换掉非字母数字字符
+ return preg_replace('/[^a-z0-9-]+/', '-', strtolower(trim($brand_name)));
+ }
+
/**
* 计算使用时间
*
@@ -832,7 +767,8 @@ class WordpressSiteService
*/
public function uploadImageToWp(string $domain,$api_user, $api_secret, string $imageUrl = "fdesk_test/usedcar_crawl/20251125/ff847a6a2b3114b4c2c230455b74cd2e.jpg"): array
{
- $imageUrl = (new OssService)->generatePrivateUrl($imageUrl);
+ $process = 'image/resize,w_900/quality,Q_50/format,webp';
+ $imageUrl = (new OssService)->generatePrivateUrlResize($imageUrl,3600,$process);
$client = new Client();
diff --git a/app/process/Task.php b/app/process/Task.php
index e00b11d..82ee20b 100644
--- a/app/process/Task.php
+++ b/app/process/Task.php
@@ -3,6 +3,9 @@
namespace app\process;
use app\common\model\UsedCar;
+use app\common\model\WordpressSite;
+use app\common\model\WordpressUsedCar;
+use app\common\service\WordpressSiteService;
use support\Db;
use support\Log;
use Workerman\Crontab\Crontab;
@@ -36,6 +39,28 @@ class Task
});
+ if (getenv('ENVIRONMENT') === 'master') {
+ // 每三个小时自动归档
+ new Crontab('0 0 3 * * *', function(){
+
+ $sites = WordpressSite::where('status', 1)
+ ->get();
+ foreach ($sites as $site) {
+ $used_car_id = WordpressUsedCar::where('wp_site_id', $site['id'])
+ ->where('status', 1)
+ ->max('used_car_id');
+ $used_cars = Db::table('used_car')
+ ->where('id', '>', $used_car_id)
+ ->get();
+ foreach ($used_cars as $car) {
+ WordpressSiteService::createProduct($site['site_url'], $car['id']);
+ }
+
+ }
+
+ });
+ }
+
}
}
\ No newline at end of file