Merge branch 'feature/wp'

# Conflicts:
#	config/route.php
This commit is contained in:
2026-03-09 14:11:58 +08:00
7 changed files with 1026 additions and 1 deletions
@@ -0,0 +1,56 @@
<?php
namespace app\admin\controller;
use app\common\controller\BaseController;
use app\common\traits\crud\CrudControllerTrait;
use app\common\service\WordpressSiteService;
use support\Request;
class WordpressSiteController extends BaseController
{
use CrudControllerTrait;
protected $service;
public function __construct()
{
$this->service = new WordpressSiteService();
}
//推送,在wp站点上创建产品
public function createProduct(Request $request){
try {
$domain = $request->get('domain');
$id = $request->get('id');
$res = $this->service->createProduct($domain,$id);
return $this->success($res, '推送成功');
} catch (\Throwable $e) {
return $this->error($e->getMessage().'-'.$e->getLine().'-'.$e->getFile());
}
}
public function uploadImageToWp(Request $request){
try {
$domain = $request->get('domain');
$res = $this->service->uploadImageToWp($domain);
return $this->success($res, '推送成功');
} catch (\Throwable $e) {
return $this->error($e->getMessage());
}
}
/**
* 列表页数据格式化
*
* @param array $data
* @return array
*/
// protected function indexFormat($data)
// {
// if (isset($data['created_at']))
// $data['created_at'] = date('Y-m-d H:i:s', $data['created_at']);
// if (isset($data['updated_at']))
// $data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']);
// return $data;
// }
}
+49
View File
@@ -0,0 +1,49 @@
<?php
namespace app\common\model;
use support\Model;
class WordpressSite extends Model
{
/**
* The connection name for the model.
*
* @var string|null
*/
protected $connection = 'mysql';
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'wordpress_site';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = true;
protected $dateFormat = 'U';
/**
* 允许自动填充模型字段
*/
protected $fillable = ['id', 'site_name', 'site_url', 'tpl_type', 'admin_url', 'api_base_url', 'auth_type', 'api_user', 'api_secret', 'exchange_rate', 'categories', 'status', 'sort', 'last_push_at', 'remark', 'locale', 'last_uid', 'created_at', 'updated_at'];
/**
* 不允许自动填充模型字段
*/
protected $guarded = [];
}
+49
View File
@@ -0,0 +1,49 @@
<?php
namespace app\common\model;
use support\Model;
class WordpressUsedCar extends Model
{
/**
* The connection name for the model.
*
* @var string|null
*/
protected $connection = 'mysql';
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'wordpress_used_car';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = true;
protected $dateFormat = 'U';
/**
* 允许自动填充模型字段
*/
protected $fillable = ['id', 'wp_site_id', 'used_car_id', 'wp_post_id', 'status', 'request_payload', 'response_body', 'error_message', 'retry_count', 'pushed_at', 'created_at', 'updated_at'];
/**
* 不允许自动填充模型字段
*/
protected $guarded = [];
}
+804
View File
@@ -0,0 +1,804 @@
<?php
namespace app\common\service;
use app\common\model\UsedCar;
use app\common\model\UsedcarCrawlResults;
use app\common\model\UsedcarCrawlResultsImages;
use app\common\model\WordpressUsedCar;
use app\common\validate\WordpressSiteValidate;
use app\common\traits\crud\CrudServiceTrait;
use app\common\model\WordpressSite;
use GuzzleHttp\Client;
use GuzzleHttp\RequestOptions;
use support\Log;
use support\Request;
use support\Response;
class WordpressSiteService
{
use CrudServiceTrait;
/**
* 指定当前要操作的模型
*/
protected string $modelClass = WordpressSite::class;
/**
* 验证器
*/
protected $validator = WordpressSiteValidate::class;
/**
* 获取验证器
*/
public function getValidator()
{
return new $this->validator;
}
/**
* @param Request $request
* @return mixed|Response
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function createPost(Request $request)
{
$client = new Client();
$url = "https://37car.dev.hnxinyouhe.com/wp-json/wp/v2/posts";
$data = [
"title" => "API 创建文章",
"content" => "内容来自 API",
"status" => "publish"
];
try {
$response = $client->post($url, [
RequestOptions::AUTH => ['Borderless', '3Tdw 6O02 DM6f lb2S 7T3l WG8a'],
RequestOptions::JSON => $data,
RequestOptions::VERIFY => false, // 禁用 SSL 验证
]);
$result = json_decode($response->getBody()->getContents(), true);
return $result;
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
}
/**
* @param Request $request
* @return mixed|Response
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function createProduct(string $domain, $id)
{
$site = WordpressSite::where('site_url',$domain)->first();
//判断是否重复推送
$wpUsed = WordpressUsedCar::where('wp_site_id', $site['id'])->where('used_car_id', $id)->first();
if($wpUsed && ($wpUsed['retry_count']>2 || $wpUsed['status'] ==1)){
$site->last_uid = $id;
$site->save();
return '重复推送';
}
$client = new Client();
// $url = $domain."/wp-json/wc/v3/products";
$url = $domain."/wp-json/wp/v2/product";
$row = UsedCar::where('id', $id)->first();
$ucImages = explode(",", $row->images);
//车辆相册
$images = [];
foreach ($ucImages as $ucImage) {
$image = $this->uploadImageToWp($domain, $site['api_user'], $site['api_secret'], $ucImage);
// $images[] = ['id' => $image['id']];
$images[] = $image['id'];
}
//$images = array_merge([$images[0]], $images);
//车辆详细信息
/*$detils= $this->drawDetils($row);
$detils_params_html = [];
foreach ($detils as $key => $detil) {
if(is_array($detil)){
$detil = implode(",", $detil);
}
$detils_params_html[] =$key.':'.(string)$detil;
}
$detils_params_html = implode(PHP_EOL, $detils_params_html);*/
// $detils_params_html = $this->buildVehicleDetailsTable($detils);
//语言确定目标网站的语言
$locale = match ($row['locale']) {
'en' => '英文',
'ru' => '俄语',
'ar' => '阿拉伯语',
'fr ' => '法语',
default => '英文',
};
$spark = new SparkService();
$car_name = $row['product_name'];
$car_name_locale = $spark->chat('将车辆名称翻译为'.$locale.':'.$car_name,null,[],'wpSend');
$condition_desc_locale = $spark->chat("下面是车辆的车况介绍将卖家信息去掉,包括但不限于商家名称、集团简介、经销商信息、地址、电话、商家介绍等都去掉\"".$row['condition_desc']."\"",null,[],'wpSend');
$condition_desc_locale = $spark->chat("将下列车况描述翻译为".$locale.":".$condition_desc_locale);
$data = [
"title" => $car_name_locale,
"Content" => '',
"excerpt" => '',
"type" => "simple", //单品,不走规格变体
"regular_price" => number_format(($row['price']*$site['exchange_rate']), 2),
"sku" => "",
//"featured" => true,//是否精选
"description" => $condition_desc_locale,
"stock_status" => "instock",//instock现车
// "categories" => [
// ["id" => 16],//used二手车
// ],
//"images" => $images,
"status" => 'publish', //发布状态
];
//$data['categories'][] = ["id" => $site['categories']];
$data['product_cat'] = explode(',', $site['categories']);
//车辆档案相关参数
$meta = $this->drawMeta($row);
//车身颜色
$color = '';
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 = [];
}
//属性:品牌、车体类型、颜色
$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']);
$conditionDesc_locale = $spark->chat('将车况描述翻译为'.$locale.':'.$row['condition_desc'],null,[],'wpSend');
//翻译车辆简介描述
$desc = "车辆名称:{$car_name},车辆参数:".json_encode($meta);
$vehicleDescription_locale = $spark->chat('根据给出的信息生成'.$locale.'车辆简介描述(要求简短):'.$desc,null,[],'wpSend');
$meta[] = [
'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'] = 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, [
//RequestOptions::AUTH => ['Borderless', '3Tdw 6O02 DM6f lb2S 7T3l WG8a'],
RequestOptions::AUTH => [$site['api_user'], $site['api_secret']],
RequestOptions::JSON => $data,
RequestOptions::VERIFY => false, // 禁用 SSL 验证
]);
$result = json_decode($response->getBody()->getContents(), true);
$wordpressUsedCar = [
'wp_site_id' => $site['id'],
'used_car_id' => $id,
'wp_post_id' => $result['id'],
'request_payload' => json_encode($data, JSON_UNESCAPED_UNICODE),
'response_body' => $response->getBody()->getContents(),
'status' => 1,
'retry_count' => 1,
];
WordpressUsedCar::create($wordpressUsedCar);
$site->last_uid = $id;
$site->save();
$data ['result'] = $result;
return $data;
//return $result;
} catch (\Exception $e) {
$his = WordpressUsedCar::where('wp_site_id', $site['id'])->where('used_car_id', $id)->first();
if ($his){
$his->retry_count = $his->retry_count + 1;
$his->save();
if ($his->retry_count>=3){
$site->last_uid = $id;
$site->save();
}
}else{
$wordpressUsedCar = [
'wp_site_id' => $site['id'],
'used_car_id' => $id,
'request_payload' => json_encode($data, JSON_UNESCAPED_UNICODE),
// 'response_body' => !empty($response)?$response->getBody()->getContents():$response,
'error_message' => $e->getMessage(),
'status' => 0,
'retry_count' => 1,
];
WordpressUsedCar::create($wordpressUsedCar);
}
throw new \Exception($e->getMessage());
}
}
/**
* 使用spark lite对话翻译,检查如果没有中文直接返回,有中文则翻译
* @param $spark
* @param $str
* @param $locale
* @return mixed
*/
public function sparkTransl($spark,$str,$locale)
{
if(!(preg_match('/[\x{4e00}-\x{9fff}]/u', $str) > 0)){
return $str;
};
$str = str_replace(["“", "”"], "", $str);
//翻译
$vehicleDescription_locale = $spark->chat('将“'.$str.'”翻译为'.$locale,null,[],'wpSend');
return $vehicleDescription_locale;
}
/**
* 获取meta_data字段,即ACF自定义的字段
* @param $used_detail
* @return array
* @throws \Exception
*/
public function drawMeta($used_car){
$fieldMap = [ //中文字段 → ACF 字段名
'plate_time', //上牌时间
'displacement', //排量
'mileage', //里程
'power', //马力
'body_color', //车身颜色
'source_place', //车源地
'price', //价格
];
$metaData = [];
foreach ($fieldMap as $acfKey) {
if (!empty($used_car[$acfKey])) {
$metaData[] = [
'key' => $acfKey,
'value' => $used_car[$acfKey],
];
}
}
return $metaData;
}
/**
* 安全取值
*/
public function drawDetils($row)
{
$baseInfo = $this->parseCarConfigDetail($row['format_car_info']);
return [
'Ref ID' => $row['used_car_id'],
'Model Code' => $row['model_code'] ?? $row['car_name'],
'Model Year' => $row['year'],
'Exterior Color' => value($baseInfo, 'body_color'),
'Engine' => value($baseInfo, 'engine_description'),
'Drivetrain' => value($baseInfo, 'driver_form'),
'Range' => '–',
'Seats' => value($baseInfo, 'seat_count'),
'Dim.(mm)' => value($baseInfo, 'length_width_height'),
'Weight(kg)' => value($baseInfo, 'curb_weight'),
'Steering' => 'Left',
'Body Type' => value($baseInfo, 'car_body_struct'),
'Mlg(km)' => $row['usage_mileage'],
'Fuel' => $row['fuel_form'],
'Transmission' => value($baseInfo, 'gearbox_description'),
'Batt.Cap.(kWh)' => value($baseInfo, 'battery_capacity'),
'Motor Power(kW)' => value($baseInfo, 'motor_power'),
'M³' => value($baseInfo, 'cargo_volume'),
'Doors' => value($baseInfo, 'door_nums'),
];
}
/**
* 安全取值
*/
function value(array $array, string $key, $default = '–')
{
if (!isset($array[$key]) || $array[$key] === '' || $array[$key] === null) {
return $default;
}
return $array[$key];
}
/**
* 将 format_car_info 拉平成 key => value
*
* @param string $json
* @return array
*/
function parseCarConfigDetail(string $json): array
{
$data = json_decode($json, true);
if (!is_array($data)) {
return [];
}
$result = [];
foreach ($data as $group) {
if (!isset($group['items']) || !is_array($group['items'])) {
continue;
}
foreach ($group['items'] as $item) {
if (!isset($item['key'])) {
continue;
}
$result[$item['key']] = $item['value'] ?? '';
}
}
return $result;
}
/**
* 从 config_detail 中提取配置信息,拉平成 key => value
*
* @param array $configDetail
* @return array
*/
private function parseConfigDetail(array $configDetail): array
{
if (!is_array($configDetail)) {
return [];
}
$result = [];
foreach ($configDetail as $group) {
if (!isset($group['items']) || !is_array($group['items'])) {
continue;
}
foreach ($group['items'] as $item) {
if (!isset($item['key'])) {
continue;
}
$key = $item['key'];
$value = $item['value'] ?? '';
// 如果值不为空,存储它(如果已存在相同key,保留第一个非空值)
if ($value !== '' && $value !== null && (!isset($result[$key]) || $result[$key] === '')) {
$result[$key] = $value;
}
}
}
return $result;
}
/**
* 从 config_detail 中获取指定配置项的值
*
* @param array $configDetail
* @param string|array $keys 要查找的key,可以是字符串或数组(多个可能的key)
* @param string $default 默认值
* @return string
*/
private function getConfigValue($configDetail, $keys, $default = ''): string
{
if (!is_array($configDetail)) {
return $default;
}
$keysToSearch = is_array($keys) ? $keys : [$keys];
foreach ($configDetail as $group) {
if (!isset($group['items']) || !is_array($group['items'])) {
continue;
}
foreach ($group['items'] as $item) {
if (!isset($item['key'])) {
continue;
}
$itemKey = $item['key'];
$itemValue = $item['value'] ?? '';
// 检查是否匹配任何要查找的key
foreach ($keysToSearch as $searchKey) {
if ($itemKey === $searchKey && $itemValue !== '' && $itemValue !== null) {
return (string)$itemValue;
}
}
}
}
return $default;
}
/**
* 查询wp车身类型
* @param $brand_name
* @return mixed
* @throws \GuzzleHttp\Exception\GuzzleException
*/
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)));
}
/**
* 计算使用时间
*
* @param string $licenseDate 上牌时间,格式可能是 YYYY-MM-DD 或其他
* @return string|null
*/
private function calculateUsageTime($licenseDate): ?string
{
if (empty($licenseDate)) {
return null;
}
try {
// 尝试解析日期
$date = null;
if (preg_match('/^(\d{4})-(\d{1,2})-(\d{1,2})/', $licenseDate, $matches)) {
$date = new \DateTime($matches[1] . '-' . $matches[2] . '-' . $matches[3]);
} elseif (preg_match('/^(\d{4})-(\d{1,2})/', $licenseDate, $matches)) {
$date = new \DateTime($matches[1] . '-' . $matches[2] . '-01');
} elseif (is_numeric($licenseDate) && strlen($licenseDate) == 10) {
// Unix时间戳
$date = new \DateTime('@' . $licenseDate);
}
if (!$date) {
return null;
}
$now = new \DateTime();
$diff = $now->diff($date);
$years = $diff->y;
$months = $diff->m;
if ($years > 0) {
$months += $years * 12;
}
if ($months == 0) {
// 如果不到1个月,显示天数
$days = $diff->days;
if ($days > 0) {
return $days == 1 ? "1 day" : "{$days} days";
}
return null;
}
if ($months == 1) {
return "1 month";
} else {
return "{$months} months";
}
} catch (\Exception $e) {
Log::error('计算使用时间失败', ['license_date' => $licenseDate, 'error' => $e->getMessage()]);
return null;
}
}
/**
* 获取内饰颜色
*
* @param array $configDetail
* @param array $baseInfo
* @return string
*/
private function getInteriorColor($configDetail, $baseInfo): string
{
$possibleKeys = ['nsys', 'interior_color', 'interiorColor', 'seat_color', 'seatColor', '内饰颜色'];
// 优先从 configDetail 中查找
$color = $this->getConfigValue($configDetail, $possibleKeys, '');
if (!empty($color) && $color !== '–') {
return $color;
}
// 如果 configDetail 中没有找到,尝试通过中文字段名查找
if (is_array($configDetail)) {
foreach ($configDetail as $group) {
if (isset($group['items']) && is_array($group['items'])) {
foreach ($group['items'] as $item) {
// 检查中文字段名
if (isset($item['name']) && (strpos($item['name'], '内饰') !== false || strpos($item['name'], '座椅') !== false)) {
if (!empty($item['value']) && $item['value'] !== '–') {
return $item['value'];
}
}
}
}
}
}
// 最后尝试从 baseInfo 中查找
foreach ($possibleKeys as $key) {
if (!empty($baseInfo[$key]) && $baseInfo[$key] !== '–') {
return $baseInfo[$key];
}
}
return '';
}
/**
* 将颜色翻译为英文
*
* @param string $color 颜色(可能是中文)
* @return string
*/
private function translateColorToEnglish($color): string
{
if (empty($color)) {
return '';
}
$colorMap = [
'白色' => 'white',
'黑色' => 'black',
'红色' => 'red',
'蓝色' => 'blue',
'绿色' => 'green',
'黄色' => 'yellow',
'银色' => 'silver',
'灰色' => 'gray',
'灰色' => 'grey',
'棕色' => 'brown',
'金色' => 'gold',
'橙色' => 'orange',
'紫色' => 'purple',
'粉色' => 'pink',
'米色' => 'beige',
'浅色' => 'light-colored',
'深色' => 'dark-colored',
];
$colorLower = mb_strtolower(trim($color), 'UTF-8');
// 如果已经是英文,直接返回(转小写)
if (preg_match('/^[a-z\s-]+$/i', $color)) {
return strtolower($color);
}
// 查找中文映射
foreach ($colorMap as $cn => $en) {
if (strpos($colorLower, $cn) !== false) {
return $en;
}
}
// 如果没有找到映射,尝试提取可能的英文部分,否则返回原值
if (preg_match('/[a-z]+/i', $color, $matches)) {
return strtolower($matches[0]);
}
return strtolower($color);
}
/**
* 构建 Vehicle Details 4列表格(2组 Key/Value)
*
* @param array $items [['label'=>'Ref ID','value'=>'xxx'], ...]
* @return string
*/
public function buildVehicleDetailsTable(array $items): string
{
$html = '<table class="vehicle-details"><tbody>';
// 每行 2 个字段(4 列)
$chunks = array_chunk($items, 2,true );
foreach ($chunks as $row) {
$html .= '<tr>';
foreach ($row as $label => $value) {
$label = htmlspecialchars($label);
$value = htmlspecialchars((string)($value ?: '–'));
$html .= "<th>{$label}</th><td>{$value}</td>";
}
// 如果是奇数,补空列
if (count($row) === 1) {
$html .= '<th></th><td></td>';
}
$html .= '</tr>';
}
$html .= '</tbody></table>';
return $html;
}
/**
* 上传 OSS 图片到 WordPress 媒体库
*
* @param string $domain
* @param string $imageUrl 阿里云 OSS 图片地址
* @return array
* @throws \Exception
*/
public function uploadImageToWp(string $domain,$api_user, $api_secret, string $imageUrl = "fdesk_test/usedcar_crawl/20251125/ff847a6a2b3114b4c2c230455b74cd2e.jpg"): array
{
$process = 'image/resize,w_900/quality,Q_50/format,webp';
$imageUrl = (new OssService)->generatePrivateUrlResize($imageUrl,3600,$process);
$client = new Client();
$filename = basename(parse_url($imageUrl, PHP_URL_PATH));
$mediaUrl = $domain . '/wp-json/wp/v2/media';
try {
// 1. 拉取 OSS 图片内容
$imageContent = file_get_contents($imageUrl);
if ($imageContent === false) {
throw new \Exception('图片下载失败:' . $imageUrl);
}
// 2. 上传到 WP 媒体库
$response = $client->post($mediaUrl, [
RequestOptions::AUTH => [$api_user, $api_secret],
RequestOptions::HEADERS => [
'Content-Disposition' => 'attachment; filename="' . $filename . '"',
'Content-Type' => 'image/jpeg', // 如有 png/webp 可自行判断
],
RequestOptions::BODY => $imageContent,
RequestOptions::VERIFY => false,
]);
return json_decode($response->getBody()->getContents(), true);
} catch (\Exception $e) {
throw new \Exception('上传图片失败:' .$domain . $imageUrl . "?????". $e->getMessage());
}
}
}
@@ -0,0 +1,29 @@
<?php
namespace app\common\validate;
use think\Validate;
class WordpressSiteValidate extends Validate
{
// 规则
protected $rule = [
];
// 提示
protected $message = [
];
// 场景
protected $scene = [
'store' => [
],
'update' => [
]
];
}
+25
View File
@@ -3,6 +3,9 @@
namespace app\process; namespace app\process;
use app\common\model\UsedCar; 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\Db;
use support\Log; use support\Log;
use Workerman\Crontab\Crontab; 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']);
}
}
});
}
} }
} }
+14 -1
View File
@@ -80,4 +80,17 @@ Route::group('/common', function () {
Route::group('/wordpress', function () { Route::group('/wordpress', function () {
Route::any('/whatsApp', [app\common\controller\WordpressVisitorController::class, 'whatsApp']); Route::any('/whatsApp', [app\common\controller\WordpressVisitorController::class, 'whatsApp']);
}); });
}); });
Route::group('/admin', function () {
//仪表盘路由规则
Route::group('/wp', function () {
Route::any('/list', [app\admin\controller\WordpressSiteController::class, 'index']);
Route::any('/show', [app\admin\controller\WordpressSiteController::class, 'show']);
Route::any('/store', [app\admin\controller\WordpressSiteController::class, 'store']);
Route::any('/update', [app\admin\controller\WordpressSiteController::class, 'update']);
Route::any('/destroy', [app\admin\controller\WordpressSiteController::class, 'destroy']);
Route::any('/send', [app\admin\controller\WordpressSiteController::class, 'createProduct']);
});
});