This commit is contained in:
2026-01-29 11:34:32 +08:00
parent e5afa43198
commit 7ecbb660d5
2 changed files with 159 additions and 198 deletions
+134 -198
View File
@@ -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' => "<ul>
<li><strong>Engine Size</strong>{$row['displacement']}</li>
<li><strong>Engine Power</strong>{$row['power']}</li>
<li><strong>Mileage(KM)</strong>{$row['mileage']}</li>
<li><strong>Color</strong>{$color}</li>
</ul>",
];
// Engine Size
//Engine Power
//Mileage
//Color
// <li><strong>Year</strong>{$row['year']}</li>
// <li><strong>Body Style</strong>{$body_style}</li>
//属性:品牌、车体类型、颜色
$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();
+25
View File
@@ -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']);
}
}
});
}
}
}