数据多语言

This commit is contained in:
2025-05-07 14:19:47 +08:00
parent 4c66404a6c
commit 3eea6db29d
19 changed files with 1989 additions and 825 deletions
+78
View File
@@ -0,0 +1,78 @@
<?php
namespace app\command;
use app\model\Vehicle;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use app\util\Xunfei;
use support\Db;
use app\model\Location;
class TransCommand extends Command
{
protected static $defaultName = 'trans';
protected static $defaultDescription = '翻译';
protected function execute(InputInterface $input, OutputInterface $output): int
{
// $list = Vehicle::all()->toArray();
// $fields = ['classify', 'brand', 'model', 'status', 'purchase_location', 'procedure_location', 'fbo_destination'];
// foreach ($list as $key => &$item) {
// foreach ($item as $k => &$v) {
// if (in_array($k, $fields)) {
// $xunfei = new Xunfei();
// $rst_dst = $xunfei->fanyi($v, 'cn', 'ar');
// if ($rst_dst) {
// $list[$key][$k] = $rst_dst["trans_result"]["dst"];
// }
// }
// }
// unset($v);
// $id = $item['id'];
// unset($item['id']);
// unset($item['created_at']);
// unset($item['updated_at']);
// Db::table('vehicles_ar')->where('id', $id)->update($item);
// $output->write("{$id}: 翻译 - 已处理 \n");
// }
// unset($item);
$list = Location::all()->toArray();
$fields = ['name', 'address', 'area'];
foreach ($list as $key => &$item) {
foreach ($item as $k => &$v) {
if (in_array($k, $fields)) {
$xunfei = new Xunfei();
$rst_dst = $xunfei->fanyi($v, 'cn', 'ru');
if ($rst_dst) {
$list[$key][$k] = $rst_dst["trans_result"]["dst"];
}
}
}
unset($v);
$id = $item['id'];
unset($item['id']);
unset($item['created_at']);
unset($item['updated_at']);
Db::table('locations_ru')->where('id', $id)->update($item);
$output->write("{$id}: 翻译 - 已处理 \n");
}
unset($item);
return self::SUCCESS;
}
}
+1 -3
View File
@@ -8,9 +8,7 @@ class IndexController
{
public function index(Request $request)
{
return view('index/location');
header('Location: https://dashboard-server.hesuu.com/app/admin');
return;
return redirect('http://219.157.255.213:25505/app/admin');
static $readme;
if (!$readme) {
$readme = file_get_contents(base_path('README.md'));
+105 -16
View File
@@ -3,10 +3,20 @@
namespace app\controller;
use app\model\Vehicle;
use app\model\VehicleEn;
use app\model\VehicleRu;
use app\model\VehicleAr;
use app\model\Location;
use app\model\LocationEn;
use app\model\LocationRu;
use app\model\LocationAr;
use app\service\OssService;
use plugin\admin\app\model\Location;
// use plugin\admin\app\model\Location;
use util\Util;
use support\Request;
use support\Cache;
class VehicleController
{
@@ -28,26 +38,85 @@ class VehicleController
*/
public function index(Request $request)
{
$vehicles = Vehicle::with('location')->with('finalLocation')->get();
$vehicles->each(function ($vehicle) {
$lang = $request->post('lang', 'zh');
switch ($lang) {
case 'zh':
$vehicles = Vehicle::with('location')->with('finalLocation')->get();
$hz = new Location();
break;
case 'en':
$vehicles = VehicleEn::with('location')->with('finalLocation')->get();
$hz = new LocationEn();
break;
case 'ru':
$vehicles = VehicleRu::with('location')->with('finalLocation')->get();
$hz = new LocationRu();
break;
case 'ar':
$vehicles = VehicleAr::with('location')->with('finalLocation')->get();
$hz = new LocationAr();
break;
}
// // $vehicles = Vehicle::with('location')->with('finalLocation')->get();
// $vehicles->each(function ($vehicle) use ($hz) {
// if (isset($vehicle->vin)) {
// $vehicle->vin = $this->maskVin($vehicle->vin);
// }
// // $vehicle->status = $this->status[$vehicle->status]??$this->status[0];
// // $location = Location::find($vehicle->locations_id);
// // $vehicle->location_name = $location ? $location->name : '';
// // $final_location = Location::find($vehicle->final_locations_id);
// // $vehicle->final_location_name = $final_location ? $final_location->name : '';
// $fbo_location = $hz->find($vehicle->fbo_locations_id);
// $vehicle->fbo_destination = $fbo_location ? $fbo_location->name : '';
// if(!str_starts_with($vehicle['img_url'], 'http')){
// $ossservice = new OssService();
// $img_url = $ossservice->generatePrivateUrl($vehicle['img_url'],86400);
// $vehicle['img_url'] = $img_url;
// }
// });
// =================================== new ===================================== start
// 单独处理 locations
$fboIds = $vehicles->pluck('fbo_locations_id')->toArray();
$fbo = $hz->whereIn('id', array_unique($fboIds))->get()->toArray();
$arr = [];
foreach ($fbo as $value) {
$arr[$value['id']] = $value;
}
// 组装数据
foreach ($vehicles as &$vehicle) {
if (isset($vehicle->vin)) {
$vehicle->vin = $this->maskVin($vehicle->vin);
}
// $vehicle->status = $this->status[$vehicle->status]??$this->status[0];
// $location = Location::find($vehicle->locations_id);
// $vehicle->location_name = $location ? $location->name : '';
// $final_location = Location::find($vehicle->final_locations_id);
// $vehicle->final_location_name = $final_location ? $final_location->name : '';
$fbo_location = Location::find($vehicle->fbo_locations_id);
$vehicle->fbo_destination = $fbo_location ? $fbo_location->name : '';
$vehicle->fbo_destination = isset($arr[$vehicle->fbo_locations_id]) ? $arr[$vehicle->fbo_locations_id]['name'] : '';
if(!str_starts_with($vehicle['img_url'], 'http')){
$ossservice = new OssService();
$img_url = $ossservice->generatePrivateUrl($vehicle['img_url'],86400);
$vehicle['img_url'] = $img_url;
$img_url = Cache::get('img_'.$vehicle->id);
if ($img_url) {
$vehicle['img_url'] = $img_url;
} else {
$ossservice = new OssService();
$img_url = $ossservice->generatePrivateUrl($vehicle['img_url'],86400);
$vehicle['img_url'] = $img_url;
Cache::set('img_'.$vehicle->id, $img_url, 86390);
}
}
});
}
unset($vehicle);
// =================================== new ===================================== end
$result = ['list' => $vehicles,'count'=>count($vehicles)];
return Util::success($result);
}
@@ -57,7 +126,27 @@ class VehicleController
*/
public function show(Request $request, $id)
{
$vehicle = Vehicle::with('location')->find($id);
$lang = $request->post('lang', 'zh');
switch ($lang) {
case 'zh':
$vehicle = Vehicle::with('location')->find($id);
break;
case 'en':
$vehicle = VehicleEn::with('location')->find($id);
break;
case 'ru':
$vehicle = VehicleRu::with('location')->find($id);
break;
case 'ar':
$vehicle = VehicleAr::with('location')->find($id);
break;
}
// $vehicle = Vehicle::with('location')->find($id);
if (!$vehicle) {
return Util::fail($vehicle,'Vehicle not found');
}
+61
View File
@@ -0,0 +1,61 @@
<?php
namespace app\model;
use support\Model;
class LocationAr extends Model
{
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'locations_ar';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = false;
/**
* Get the vehicles for the location.
*/
public function vehicles()
{
return $this->hasMany(VehicleAr::class, 'locations_id', 'id');
}
/**
* 目的地关联
* Get the vehicles for the location.
*/
public function finalVehicles()
{
return $this->hasMany(VehicleAr::class, 'final_locations_id', 'id');
}
/**
* Get the FBO vehicles for the location.
*/
public function fboVehicles()
{
return $this->hasMany(VehicleAr::class, 'fbo_locations_id', 'id');
}
/**
* Scope a query to only include locations that have vehicles.
*/
public function scopeHasVehicles($query)
{
return $query->whereHas('vehicles_ar');
}
}
+61
View File
@@ -0,0 +1,61 @@
<?php
namespace app\model;
use support\Model;
class LocationEn extends Model
{
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'locations_en';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = false;
/**
* Get the vehicles for the location.
*/
public function vehicles()
{
return $this->hasMany(VehicleEn::class, 'locations_id', 'id');
}
/**
* 目的地关联
* Get the vehicles for the location.
*/
public function finalVehicles()
{
return $this->hasMany(VehicleEn::class, 'final_locations_id', 'id');
}
/**
* Get the FBO vehicles for the location.
*/
public function fboVehicles()
{
return $this->hasMany(VehicleEn::class, 'fbo_locations_id', 'id');
}
/**
* Scope a query to only include locations that have vehicles.
*/
public function scopeHasVehicles($query)
{
return $query->whereHas('vehicles_en');
}
}
+61
View File
@@ -0,0 +1,61 @@
<?php
namespace app\model;
use support\Model;
class LocationRu extends Model
{
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'locations_ru';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = false;
/**
* Get the vehicles for the location.
*/
public function vehicles()
{
return $this->hasMany(VehicleRu::class, 'locations_id', 'id');
}
/**
* 目的地关联
* Get the vehicles for the location.
*/
public function finalVehicles()
{
return $this->hasMany(VehicleRu::class, 'final_locations_id', 'id');
}
/**
* Get the FBO vehicles for the location.
*/
public function fboVehicles()
{
return $this->hasMany(VehicleRu::class, 'fbo_locations_id', 'id');
}
/**
* Scope a query to only include locations that have vehicles.
*/
public function scopeHasVehicles($query)
{
return $query->whereHas('vehicles_ru');
}
}
+46
View File
@@ -0,0 +1,46 @@
<?php
namespace app\model;
use support\Model;
class VehicleAr extends Model
{
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'vehicles_ar';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = false;
/**
* Get the location that owns the vehicle.
*/
public function location()
{
return $this->belongsTo(LocationAr::class, 'locations_id', 'id');
}
/**
* Get the location that owns the vehicle.
*/
public function finalLocation()
{
return $this->belongsTo(LocationAr::class, 'final_locations_id', 'id');
}
}
+46
View File
@@ -0,0 +1,46 @@
<?php
namespace app\model;
use support\Model;
class VehicleEn extends Model
{
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'vehicles_en';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = false;
/**
* Get the location that owns the vehicle.
*/
public function location()
{
return $this->belongsTo(LocationEn::class, 'locations_id', 'id');
}
/**
* Get the location that owns the vehicle.
*/
public function finalLocation()
{
return $this->belongsTo(LocationEn::class, 'final_locations_id', 'id');
}
}
+46
View File
@@ -0,0 +1,46 @@
<?php
namespace app\model;
use support\Model;
class VehicleRu extends Model
{
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'vehicles_ru';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = false;
/**
* Get the location that owns the vehicle.
*/
public function location()
{
return $this->belongsTo(LocationRu::class, 'locations_id', 'id');
}
/**
* Get the location that owns the vehicle.
*/
public function finalLocation()
{
return $this->belongsTo(LocationRu::class, 'final_locations_id', 'id');
}
}
+134
View File
@@ -0,0 +1,134 @@
<?php
namespace app\util;
class Xunfei
{
protected $error = "";
public function tocurl($url, $header, $content)
{
$ch = curl_init();
if(substr($url,0,5)=='https'){
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
curl_setopt($ch, CURLOPT_SSLVERSION, 1);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $url);
if (is_array($header)) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
}
curl_setopt($ch, CURLOPT_POST, true);
if (!empty($content)) {
if (is_array($content)) {
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($content));
} else if (is_string($content)) {
curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
}
}
$response = curl_exec($ch);
$error=curl_error($ch);
//var_dump($error);
if($error){
die($error);
}
$header = curl_getinfo($ch);
curl_close($ch);
$data = array('header' => $header,'body' => $response);
return $data;
}
public function xfyun($text = "中华人民共和国于1949年成立", $from = "cn", $to = "en")
{
//在控制台-我的应用-机器翻译获取
$app_id = "3d46198c";
//在控制台-我的应用-机器翻译获取
$api_sec = "ZWY2MmUyNjJjYmFkOTFlYTVmYWVhMGYy";
//在控制台-我的应用-机器翻译获取
$api_key = "b6d805f240176ecaea85130cb5f2bca1";
// 机器翻译接口地址
$url = "https://ntrans.xfyun.cn/v2/ots";
//body组装
// $text = "中华人民共和国于1949年成立";//待翻译文本
$body = json_encode($this->getBody($app_id, $from, $to, $text));
// 组装http请求头
$date =gmdate('D, d M Y H:i:s') . ' GMT';
$digestBase64 = "SHA-256=".base64_encode(hash("sha256", $body, true));
$builder = sprintf("host: %s
date: %s
POST /v2/ots HTTP/1.1
digest: %s", "ntrans.xfyun.cn", $date, $digestBase64);
// echo($builder);
$sha = base64_encode(hash_hmac("sha256", $builder, $api_sec, true));
$authorization = sprintf("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", $api_key,"hmac-sha256",
"host date request-line digest", $sha);
$header = [
"Authorization: ".$authorization,
'Content-Type: application/json',
'Accept: application/json,version=1.0',
'Host: ntrans.xfyun.cn',
'Date: ' .$date,
'Digest: '.$digestBase64
];
$response = $this->tocurl($url, $header, $body);
// var_dump($response['body']);
return $response;
}
public function getBody($app_id, $from, $to, $text)
{
$common_param = [
'app_id' => $app_id
];
$business = [
'from' => $from,
'to' => $to,
];
$data = [
"text" => base64_encode($text)
];
return $body = [
'common' => $common_param,
'business' => $business,
'data' => $data
];
}
// 翻译
public function fanyi($text = "", $from = "", $to = "")
{
try {
$res = $this->xfyun($text, $from, $to);
$data = json_decode($res["body"], true);
if ($data["code"] === 0) {
return $data["data"]["result"];
} else {
$this->error = $data["message"];
return false;
}
} catch (\Throwable $th) {
$this->error = $th->getMessage();
return false;
}
}
// 异常
public function error()
{
return $this->error;
}
}