car/application/admin/controller/wechat/Api.php
2025-07-15 17:55:06 +08:00

313 lines
9.1 KiB
PHP

<?php
namespace app\admin\controller\wechat;
use app\admin\model\car\Attributes;
use app\admin\model\car\AttributeValue;
use app\admin\model\Cars;
use app\common\controller\Backend;
use think\Db;
/**
*
*
* @icon fa fa-circle-o
*/
class Api extends Backend
{
protected $noNeedRight = ['*'];
protected $noNeedLogin = ['*'];
public function select()
{
$series = Db::query("SELECT a.id,brand_id as pid, a.name FROM series a LEFT JOIN brands b ON a.brand_id = b.id;");
$brands = Db::query("SELECT id, 0 as pid, `name` FROM brands;");
$this->series = $series;
$this->brands = $brands;
$data = array_merge($brands,$series);
$tree = $this->buildTree($data);
$formattedTree = $this->formatTree($tree);
$service = [
[
'label' => '全部',
'value' => null
]
];
foreach ($formattedTree as $item){
$item['children'] = [
[
'label' => $item['label'],
'value' => 'b_'.$item['value']
],...$item['children']
];
$service [] = $item;
}
$data = Attributes::order('sort_order')->select();
$res = [];
foreach ($data as $datum){
$datum->options = json_decode($datum->options);
$re = $datum->toArray();
$out = [
'id' => $re['id'],
'label' => $re['name'],
'type' => $re['input_type'],
'options' => $re['options'],
'name' => $re['field_key'],
'value' => $value_map[$re['id']] ?? null,
];
$res [] =$out;
}
$out = [
'brands' => $service,
'extend' => $res
];
return $this->return_json($out);
}
public function car()
{
$data = request()->post();
$build = Cars::where('is_active',1);
$attr = $data['attr'] ?? null;
$brand = $data['brand'] ?? null;
$type = $data['type'] ?? 1;
if ($attr){
$ids = $this->getAttrIds($attr);
$build->whereIn('id',$ids);
}
if ($brand){
if (str_starts_with($brand,'b')){
$build->whereIn('brand_id',str_replace('b_','',$brand));
}else{
$build->whereIn('series_id',$brand);
}
}
$build->where('car_type',$type);
$list = $build->paginate();
$res = [];
$car_ids = [];
foreach ($list->items() as $item){
$out = $item->toArray();
$car_ids [] = $item['id'];
$images = explode(',',$out['cover_image']);
$images = array_map(function($url) {
return cdnurl($url, true); // true 表示生成绝对路径
}, $images);
$out['cover_image'] = $images;
$res [] = $out;
}
$attr_value = AttributeValue::whereIn('car_id',$car_ids)->select();
$attr_array = [];
foreach ($attr_value as $item){
$attr_array [] = $item->toArray();
}
$attr_field = Attributes::order('sort_order')->select();
$attr_field_array = [];
foreach ($attr_field as $datum){
$datum->options = json_decode($datum->options,true);
$re = $datum->toArray();
$out = [
'id' => $re['id'],
'label' => $re['name'],
'type' => $re['input_type'],
'options' => $re['options'],
'name' => $re['field_key'],
'sort_order' => $re['sort_order'],
];
$attr_field_array [] =$out;
}
$car_attr_map = $this->mapAllCarAttributesSorted($attr_array,$attr_field_array);
foreach ($res as &$re){
if (isset($car_attr_map[$re['id']])){
$re['attr'] = array_splice($car_attr_map[$re['id']],0,3);
}
}
return $this->return_json(
[
'total' => $list->total(),
'items' => $res
]
);
}
public function banners()
{
$banner = config('site.banner_images'); // 获取轮播图数组
$out = [];
foreach ($banner as $item){
$out [] = cdnurl($item);
}
return $this->return_json($out);
}
public function carInfo()
{
$id = request()->get('id');
$build = Cars::where('is_active',1)->where('id',$id)->with([
'brand','series'
]);
$car = $build->select()[0];
if (!$car){
return $this->return_json([],'未找到信息',code: 0);
}
$car = $car->toArray();
$images = explode(',',$car['cover_image']);
$images = array_map(function($url) {
return cdnurl($url, true); // true 表示生成绝对路径
}, $images);
$car['cover_image'] = $images;
$attr_value = AttributeValue::where('car_id',$car['id'])->select();
$attr_array = [];
foreach ($attr_value as $item){
$attr_array [] = $item->toArray();
}
$attr_field = Attributes::order('sort_order')->select();
$attr_field_array = [];
foreach ($attr_field as $datum){
$datum->options = json_decode($datum->options,true);
$re = $datum->toArray();
$out = [
'id' => $re['id'],
'label' => $re['name'],
'type' => $re['input_type'],
'options' => $re['options'],
'name' => $re['field_key'],
'sort_order' => $re['sort_order'],
];
$attr_field_array [] =$out;
}
$car_attr_map = $this->mapAllCarAttributesSorted($attr_array,$attr_field_array);
$car['attr'] = $car_attr_map[$car['id']];
return $this->return_json($car);
}
private function mapAllCarAttributesSorted(array $carAttributes, array $attributeDefs): array
{
// 把属性定义按 id 映射为键,并附带 sort_order
$defMap = [];
foreach ($attributeDefs as $def) {
$defMap[$def['id']] = $def;
}
// 先聚合 car_id 下的属性条目
$cars = [];
foreach ($carAttributes as $attr) {
$carId = $attr['car_id'];
$attributeId = $attr['attribute_id'];
$value = $attr['value'];
if (!isset($defMap[$attributeId])) continue;
$def = $defMap[$attributeId];
$label = $def['label'];
$type = $def['type'];
$sortOrder = $def['sort_order'];
$key = null;
if ($type === 'checkbox') {
foreach ($def['options'] as $opt) {
if ((string)$opt['value'] === (string)$value) {
$key = $opt['key'];
break;
}
}
} elseif ($type === 'range') {
$key = $value . $def['options']['unit'];
}
if (!is_null($key)) {
$cars[$carId][] = [
'label' => $label,
'key' => $key,
'sort_order' => $sortOrder
];
}
}
// 对每个 car_id 下的属性按 sort_order 排序,并转成 label => key 格式
$result = [];
foreach ($cars as $carId => $items) {
usort($items, function($a, $b) {
return $a['sort_order'] <=> $b['sort_order'];
});
foreach ($items as $item) {
$result[$carId][$item['label']] = $item['key'];
}
}
return $result;
}
private function getAttrIds($attrs)
{
$attrDB = Attributes::field('id,field_key,input_type')->select();
$attr_array = [];
foreach ($attrDB as $item){
$attr_array[] = $item->toArray();
}
$attr_map = array_column($attr_array,null,'field_key');
$car_id = [];
foreach ($attrs as $key=>$item) {
if (isset($attr_map[$key])){
$field = $attr_map[$key];
if ($field['input_type'] == 'checkbox'){
$ids = AttributeValue::where('attribute_id',$field['id'])
->whereIn('value',$item)->column('DISTINCT car_id');
if ($car_id){
$car_id = array_intersect($car_id,$ids);
}else{
$car_id = $ids;
}
}elseif ($field['input_type'] == 'range'){
$ids = AttributeValue::where('attribute_id',$field['id'])
->where('value','>=',$item['start'])
->where('value','<=',$item['end'])
->column('DISTINCT car_id');
if ($car_id){
$car_id = array_intersect($car_id,$ids);
}else{
$car_id = $ids;
}
}
}
}
return array_values(array_unique($car_id));
}
}