Files
useds/app/common/controller/UsedCarController.php
T
2026-01-16 18:25:25 +08:00

507 lines
19 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace app\common\controller;
use app\common\model\UsedCar;
use app\common\model\UsedCarPdfLog;
use app\common\model\User;
use app\common\service\OssService;
use app\common\service\SparkService;
use app\common\traits\crud\CrudControllerTrait;
use app\common\service\UsedCarService;
use app\common\utils\crawl\service\UsedCarCrawlSingle;
use app\common\utils\pdf\service\MpdfDriver;
use support\exception\BusinessException;
use support\Request;
class UsedCarController extends BaseController
{
use CrudControllerTrait;
protected $service;
protected $noNeedLogin = ['downloadPdf'];
protected $noNeedHeaderData = ['downloadPdf'];
protected $lang = [
'en' => '英语',
'ru' => '俄语',
'es' => '西班牙语',
'ar' => '阿拉伯语',
];
protected $currency = [
'USD' => '$',
'RUB' => '₽',
'AED' => 'د.إ',
'EUR' => '€',
'CNY' => '¥',
];
public function __construct()
{
$this->service = new UsedCarService();
}
/**
* 更新状态
* @return \support\Response
*/
public function status(Request $request){
try {
$data = $request->post();
$res = $this->service->serviceUpdateStatus($request, $data);
return $this->success([], '更新成功');
} 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']);
if (!empty($data['images'])){
$images = explode(',', $data['images']);
$ossService = new OssService();
$images_pull = [];
foreach ($images as $image){
$images_pull[] = $ossService->generatePrivateUrl($image);
}
$data['images_pull'] = $images_pull;
}
return $data;
}
/**
* 列表页数据格式化
*
* @param array $data
* @return array
*/
protected function showFormat($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']);
if (!empty($data['images'])){
$images = explode(',', $data['images']);
$ossService = new OssService();
$images_pull = [];
foreach ($images as $image){
$images_pull[] = $ossService->generatePrivateUrl($image);
}
$data['images_pull'] = $images_pull;
}else{
$data['images_pull'] = [];
}
if (!empty($data['attachment'])){
//$attachments = explode(',', $data['attachment']);
$attachments = json_decode($data['attachment'], true);
$ossService = new OssService();
$attachment_pull = [];
foreach ($attachments as $attachment){
$attachment_pull[] = [
'name'=>$attachment['name'],
'src'=>$attachment['src'],
'src_pull'=>$ossService->generatePrivateUrl($attachment['src']),
];
}
$data['attachment_pull'] = $attachment_pull;
}else{
$data['attachment_pull'] = [];
}
return $data;
}
public function crawlCar(Request $request)
{
try {
$url = $request->get('url');
if (empty($url)){
throw new BusinessException('url不能为空');
}
$info = (new UsedCarCrawlSingle())->crawlCar($url);
$data = [
'user_id' => $request->user['id'],
'product_name' => $info['title'],
'price' => $info['price']<200 ? $info['price']*10000 : $info['price'],
'source_place' => $info['source_place'],
'displacement' => $info['capacity'], //排量
'mileage' => $info['usage_mileage']*10000, //里程
'power' => $info['horsepower'], //马力
'body_color' => $info['body_color'],
'images' => $info['image'],
'image_pull' => $info['image_pull'],
'condition_desc' => $info['condition_desc'],
'attachment' => '',
'source_url' => $url,
'crawl_car_id' => $info['car_id'],
'crawl_brand_id' => $info['brand_id'],
'crawl_series_id' => $info['series_id'],
'used_car_id' => $info['used_car_id'],
'plate_time' => $info['plate_time'],
];
return $this->success($data);
} catch (\Throwable $e) {
return $this->error($e->getMessage().'|'.$e->getLine().$e->getFile().$e->getTraceAsString());
}
}
public function crawlKeyword(Request $request){
try {
// $keyword = $request->get('keyword');
$data = $this->service->crawlKeyword($request);
return $this->success($data);
} catch (\Throwable $e) {
return $this->error($e->getMessage());
}
}
/**
* 生成pdf
* @param Request $request
* @return \support\Response
*/
public function producePdf(Request $request){
try {
$price = $request->get('price');
$lang = $request->get('lang');
$currency = $request->get('currency');
$trade = $request->get('trade_term');
if(empty($price)){
throw new BusinessException("请输入生成pdf中的价格");
}
if(empty($lang) || empty($this->lang[$lang])){
throw new BusinessException("语种错误");
}
if(empty($currency) || empty($this->currency[$currency])){
throw new BusinessException("币种错误");
}
$raw = $this->service->serviceShow($request);
$data = $this->transformData($raw, method_exists($this, 'showFormat')
? [$this, 'showFormat']
: null);
$images = [];
foreach ($data['images_pull'] as $image){
$images[] = $this->service->downloadImage($image);
}
$data['images'] = $images;
$attachments = [];
foreach ($data['attachment_pull'] as $attachment){
// 方法1:使用 pathinfo
$path = parse_url($attachment['src'], PHP_URL_PATH); // 获取路径部分
$extension = pathinfo($path, PATHINFO_EXTENSION); // 获取扩展名
if (strtolower($extension) === 'pdf') { //如果是pdf则下载到本地
$attachments[] = $this->service->downloadAttachment($attachment['src']);
}
}
$data['attachment'] = $attachments;
$data['price'] = $price;
$user = User::where('id',$request->user['id'])->first();
$contact = $user['email'] ?? $user['phone'] ?? $user['whatsapp'] ?? null;
if(!empty($user['social_code'])){
$ossService = new OssService();
$user['social_code'] = $ossService->generatePrivateUrl($user['social_code']);
$user['social_code'] = $this->service->downloadImage($user['social_code']);
}
$field = $this->field($lang);//字段相关外文
$field['currency'] = $this->currency[$currency];
$data['product_name'] = $data['crawl_brand'].' '.$data['crawl_series'].' '.$data['crawl_title'];
$data = $this->fanyi($data, $lang);//车辆字段翻译外文
$contactField = $this->contact($lang); //名片相关外文
$data['trade'] = $trade;
$pdf = (new MpdfDriver())->exportUsedCarPdf($field,$data,$user,$contactField,$contact,$lang);
UsedCar::where('id', $data['id'])->update(['pdf_src' => $pdf]);
array_map('unlink', glob(runtime_path('pdf/images/*.jpg')));
array_map('unlink', glob(runtime_path('pdf/attachment/*.pdf')));
UsedCarPdfLog::create([
'user_id' => $request->user['id'],
'used_car_id' => $request->get('id'),
'price_snapshot' => $price,
'pdf_path' => $pdf,
]);
return $this->success($pdf);
} catch (\Throwable $e) {
return $this->error($e->getMessage().$e->getLine().$e->getFile());
}
}
public function downloadPdf(Request $request){
$raw = $this->service->serviceShow($request);
$filePath = runtime_path('pdf') .'/'. $raw['pdf_src'];
if (!file_exists($filePath)) {
return response($filePath.'文件不存在', 404);
}
return response()->download(
$filePath,
$raw['product_name'].'-'.$raw['id'].'.pdf' // 下载时显示的文件名
);
}
public function fanyi($data, $to){
foreach ($data as $k => $v) {
if (in_array($k, ['product_name', 'source_place', 'body_color', 'condition_desc']) && !empty(trim($v))) {
// $xunfei = new XunfeiFanyi();
// $data[$k] = $xunfei->fanyi($v, $from = 'cn', $to);
$toLang = $this->lang[$to];
$spark = new SparkService();
$str = $spark->chat("将“{$v}”翻译为{$toLang},不要有多余的描述");
if(!empty($str)){
$str = preg_replace('/[\x{4e00}-\x{9fa5}]/u', '', $str);
$data[$k] =str_replace(['(',')','(',')','"'], '', $str);
}else{
$data[$k] = '';
}
}
}
return $data;
}
/**
* 字段名
* @param $data
* @param $to
* @return mixed
*/
public function field($to){
$field = [
'cn' => [
'price' => '车价',
'source_place' => '车源地',
'plate_time' => '上牌时间',
'displacement' => '排量',
'mileage' => '里程',
'power' => '马力',
'body_color' => '车身颜色',
'created_at' => '创建时间',
'condition_desc' => '车况介绍',
'images' => '产品图',
'trade' => '贸易条款',
],
'en' => [
'price' => 'Price',
'source_place' => 'Vehicle Location',
'plate_time' => 'Registration Date',
'displacement' => 'Engine Displacement',
'mileage' => 'Mileage',
'power' => 'Horsepower',
'body_color' => 'Body Color',
'created_at' => 'Created At',
'condition_desc' => 'Vehicle Condition',
'images' => 'Product image',
'trade' => 'Trade terms',
],
'ru' => [
'price' => 'Цена',
'source_place' => 'Местонахождение автомобиля',
'plate_time' => 'Дата регистрации',
'displacement' => 'Объём двигателя',
'mileage' => 'Пробег',
'power' => 'Мощность',
'body_color' => 'Цвет кузова',
'created_at' => 'Дата создания',
'condition_desc' => 'Состояние автомобиля',
'images' => 'Фотографии',
'trade' => 'Условия торговли',
],
'es' => [
'price' => 'Precio',
'source_place' => 'Ubicación del vehículo',
'plate_time' => 'Fecha de matriculación',
'displacement' => 'Cilindrada',
'mileage' => 'Kilometraje',
'power' => 'Potencia',
'body_color' => 'Color de la carrocería',
'created_at' => 'Fecha de creación',
'condition_desc' => 'Estado del vehículo',
'images' => 'Imagen del producto',
'trade' => 'Условия торговли',
],
'ar' => [
'price' => 'السعر',
'source_place' => 'موقع السيارة',
'plate_time' => 'تاريخ التسجيل',
'displacement' => 'سعة المحرك',
'mileage' => 'المسافة المقطوعة',
'power' => 'قوة المحرك',
'body_color' => 'لون الهيكل',
'created_at' => 'تاريخ الإنشاء',
'condition_desc' => 'حالة السيارة',
'images' => 'خريطة المنتج',
'trade' => 'شروط التجارة',
],
];
return $field[$to];
// foreach ($field as $k => $v) {
//// $xunfei = new XunfeiFanyi();
//// $field[$k] = $xunfei->fanyi($v, $from = 'cn', $to);
// $toLang = $this->lang[$to];
// $spark = new SparkService();
// $field[$k] = $spark->chat("“{$v}”翻译为{$toLang},不要有多余的描述");
// }
// return $field;
}
/**
* 名片外文
*/
public function contact($to){
$contactField = [
'cn' => [
'title' => '联系人名片',
'name' => '姓名',
'email' => '邮箱',
'phone' => '电话',
'WhatsApp' => 'WhatsApp',
'code' => '二维码',
'left' => '扫码即可联系本人',
'right' => '本资料随PDF自动生成',
],
'en' => [
'title' => 'Contact Name Card',
'name' => 'Name',
'email' => 'Email',
'phone' => 'Phone',
'WhatsApp' => 'WhatsApp',
'code' => 'QR Code',
'left' => 'Scan the code to contact me',
'right' => 'This information is automatically generated with the PDF',
],
'ru' => [
'title' => 'Контактная карточка',
'name' => 'Имя',
'email' => 'Электронная почта',
'phone' => 'Телефон',
'WhatsApp' => 'WhatsApp',
'code' => 'QR-код',
'left' => 'Код позволяет связаться с самим собой.',
'right' => 'Эта информация автоматически генерируется с помощью PDF',
],
'es' => [
'title' => 'Tarjeta de visita de contacto',
'name' => 'Nombre',
'email' => 'Correo electrónico',
'phone' => 'Teléfono',
'WhatsApp' => 'WhatsApp',
'code' => 'Código QR',
'left' => 'Escanee el Código para contactarme.',
'right' => 'Esta información se genera automáticamente con pdf',
],
'ar' => [
'title' => 'بطاقة الاتصال',
'name' => 'الاسم',
'email' => 'البريد الإلكتروني',
'phone' => 'الهاتف',
'WhatsApp' => 'واتساب',
'code' => 'رمز QR',
'left' => 'اكتساح رمز الاتصال بي',
'right' => 'هذه المعلومات تلقائيا مع قوات الدفاع الشعبي',
],
];
return $contactField[$to];
}
public function getPdf(Request $request)
{
try {
$raw = $this->service->serviceShow($request);
$filePath = runtime_path('pdf') . '/' . $raw['pdf_src'];
if (empty($raw['pdf_src']) || !file_exists($filePath)) {
throw new BusinessException('文件不存在');
}
// 确保 public/pdf 存在
$publicDir = public_path('pdf');
if (!is_dir($publicDir)) {
mkdir($publicDir, 0755, true);
}
// 拷贝到 public 目录
$publicFile = $publicDir . '/' . $raw['pdf_src'];
if (!file_exists($publicFile)) {
copy($filePath, $publicFile);
}
// 返回访问地址
$baseUrl = 'https://' . request()->header('host');
$url = $baseUrl . '/pdf/' . $raw['pdf_src'];
return $this->success([
'pdf_url' => $url,
'file_name' => $raw['product_name'] . '-' . $raw['id'] . '.pdf'
]);
} catch (\Throwable $e) {
return $this->error($e->getMessage());
}
}
/**
* 预览pdf
*/
function previewPdf($request) {
try {
$raw = $this->service->serviceShow($request);
$filePath = runtime_path('pdf') . '/' . $raw['pdf_src'];
if (empty($raw['pdf_src']) || !file_exists($filePath)) {
throw new BusinessException('文件不存在');
}
// 确保 public/pdf 存在
$publicDir = public_path('pdf');
if (!is_dir($publicDir)) {
mkdir($publicDir, 0755, true);
}
// 拷贝到 public 目录
$publicFile = $publicDir . '/' . $raw['pdf_src'];
if (!file_exists($publicFile)) {
copy($filePath, $publicFile);
}
$path = public_path('pdf/' . basename($raw['pdf_src']));
return response(file_get_contents($path), 200, [
'Content-Type' => 'application/pdf',
'Access-Control-Allow-Origin' => '*', // 或指定前端域名
'Access-Control-Allow-Methods' => 'GET, OPTIONS',
'Access-Control-Allow-Headers' => '*',
]);
} catch (\Throwable $e) {
return $this->error($e->getMessage());
}
}
}