SchoolPhysicalExamination/application/KitchenScale3/controller/app/Guessyoulike.php

807 lines
32 KiB
PHP

<?php
namespace app\KitchenScale3\controller\app;
use think\Db;
use think\Controller;
class Guessyoulike extends Controller {
protected $kitchenscale_db_msg = [
// 'cookbook' => 'app_user_cookbook', //食谱表
// 'cookbook_label' => 'app_user_cookbook_label', //食谱标签表
// 'cookbook_food_relation' => 'app_user_cookbook_food_relation', //食谱跟食材关系表
'foodlist2' => 'app_z_national_standard_food_type_2_multilingual', //食材标签表2
'foodlist3' => 'app_z_national_standard_food_type_3_multilingual', //食材表
'kcal_log' => 'app_user_kcal_log_multilingual', //用户饮食记录表记录用户吃了什么食材
'search_history' => 'app_user_search_history_multilingual', //用户搜索记录表,记录用户搜索过什么内容
// 'tag_preference' => 'app_user_tag_preference', //用户标签偏好表
'recommend_cache' => 'app_recommend_cache_multilingual' //智能推荐缓存表
];
protected $config = [
'tag_limit' => 2,
'item_limit' => 12,
'cache_time' => 3600
];
protected $translations = [
'zh' => '搜索最多的食材',
'en' => 'Most Searched Ingredients',
'jp' => '最も検索された食材',
'fra' => 'Ingrédients les Plus Recherchés',
'de' => 'Am Häufigsten Gesuchte Lebensmittel',
'kor' => '가장 많이 검색된 재료',
'ru' => 'Самые Искомые Ингредиенты',
'pt' => 'Ingredientes Mais Pesquisados',
'spa' => 'Ingredientes Más Buscados',
'ara' => 'المكونات الأكثر بحثًا'
];
protected $food_2_ys = [
'Dairy and Egg Products' => [
'zh' => '乳制品和蛋类',
'en' => 'Dairy and Egg Products',
'jp' => '乳製品と卵製品',
'fra' => 'Produits laitiers et œufs',
'de' => 'Milch- und Eiprodukte',
'kor' => '유제품 및 계란 제품',
'ru' => 'Молочные продукты и яйца',
'pt' => 'Laticínios e Ovos',
'spa' => 'Productos lácteos y huevos',
'ara' => 'منتجات الألبان والبيض'
],
'Spices and Herbs' => [
'zh' => '香料和香草',
'en' => 'Spices and Herbs',
'jp' => 'スパイスとハーブ',
'fra' => 'Épices et herbes',
'de' => 'Gewürze und Kräuter',
'kor' => '향신료 및 허브',
'ru' => 'Специи и травы',
'pt' => 'Especiarias e Ervas',
'spa' => 'Especias y hierbas',
'ara' => 'التوابل والأعشاب'
],
'Baby Foods' => [
'zh' => '婴儿食品',
'en' => 'Baby Foods',
'jp' => 'ベビーフード',
'fra' => 'Aliments pour bébés',
'de' => 'Babynahrung',
'kor' => '아기 음식',
'ru' => 'Детское питание',
'pt' => 'Alimentos para Bebês',
'spa' => 'Alimentos para bebés',
'ara' => 'أغذية الأطفال'
],
'Fats and Oils' => [
'zh' => '脂肪和油脂',
'en' => 'Fats and Oils',
'jp' => '油脂',
'fra' => 'Graisses et huiles',
'de' => 'Fette und Öle',
'kor' => '지방과 오일',
'ru' => 'Жиры и масла',
'pt' => 'Gorduras e Óleos',
'spa' => 'Grasas y aceites',
'ara' => 'الدهون والزيوت'
],
'Poultry Products' => [
'zh' => '家禽产品',
'en' => 'Poultry Products',
'jp' => '家禽製品',
'fra' => 'Produits de volaille',
'de' => 'Geflügelprodukte',
'kor' => '가금류 제품',
'ru' => 'Продукты из птицы',
'pt' => 'Produtos Avícolas',
'spa' => 'Productos avícolas',
'ara' => 'منتجات الدواجن'
],
'Soups, Sauces, and Gravies' => [
'zh' => '汤、酱汁和肉汁',
'en' => 'Soups, Sauces, and Gravies',
'jp' => 'スープ、ソース、グレービー',
'fra' => 'Soupes, sauces et jus',
'de' => 'Suppen, Saucen und Soßen',
'kor' => '수프, 소스, 그레이비',
'ru' => 'Супы, соусы и подливки',
'pt' => 'Sopas, Molhos e Caldos',
'spa' => 'Sopas, salsas y salsas',
'ara' => 'الشوربات والصلصات والمرق'
],
'Sausages and Luncheon Meats' => [
'zh' => '香肠和午餐肉',
'en' => 'Sausages and Luncheon Meats',
'jp' => 'ソーセージとランチョンミート',
'fra' => 'Saucisses et viandes froides',
'de' => 'Wurstwaren und Aufschnitt',
'kor' => '소시지와 점심 고기',
'ru' => 'Колбасные изделия и мясные нарезки',
'pt' => 'Salsichas e Carnes Frias',
'spa' => 'Salchichas y fiambres',
'ara' => 'النقانق واللحوم الباردة'
],
'Breakfast Cereals' => [
'zh' => '早餐谷物',
'en' => 'Breakfast Cereals',
'jp' => '朝食用シリアル',
'fra' => 'Céréales pour petit-déjeuner',
'de' => 'Frühstückscerealien',
'kor' => '아침 식사 시리얼',
'ru' => 'Сухие завтраки',
'pt' => 'Cereais Matinais',
'spa' => 'Cereales para el desayuno',
'ara' => 'حبوب الإفطار'
],
'Fruits and Fruit Juices' => [
'zh' => '水果和果汁',
'en' => 'Fruits and Fruit Juices',
'jp' => 'フルーツとフルーツジュース',
'fra' => 'Fruits et jus de fruits',
'de' => 'Früchte und Fruchtsäfte',
'kor' => '과일과 과일 주스',
'ru' => 'Фрукты и фруктовые соки',
'pt' => 'Frutas e Sucos de Frutas',
'spa' => 'Frutas y jugos de frutas',
'ara' => 'الفواكه وعصائر الفاكهة'
],
'Pork Products' => [
'zh' => '猪肉产品',
'en' => 'Pork Products',
'jp' => '豚肉製品',
'fra' => 'Produits de porc',
'de' => 'Schweinefleischprodukte',
'kor' => '돼지고기 제품',
'ru' => 'Свиные продукты',
'pt' => 'Produtos de Porco',
'spa' => 'Productos de cerdo',
'ara' => 'منتجات لحم الخنزير'
],
'Vegetables and Vegetable Products' => [
'zh' => '蔬菜和蔬菜制品',
'en' => 'Vegetables and Vegetable Products',
'jp' => '野菜と野菜製品',
'fra' => 'Légumes et produits végétaux',
'de' => 'Gemüse und Gemüseprodukte',
'kor' => '채소와 채소 제품',
'ru' => 'Овощи и овощные продукты',
'pt' => 'Vegetais e Produtos Vegetais',
'spa' => 'Verduras y productos vegetales',
'ara' => 'الخضروات ومنتجات الخضروات'
],
'Nut and Seed Products' => [
'zh' => '坚果和种子产品',
'en' => 'Nut and Seed Products',
'jp' => 'ナッツと種子製品',
'fra' => 'Noix et graines',
'de' => 'Nuss- und Samenprodukte',
'kor' => '견과류와 씨앗 제품',
'ru' => 'Орехи и семена',
'pt' => 'Nozes e Sementes',
'spa' => 'Frutos secos y semillas',
'ara' => 'المكسرات والبذور'
],
'Beef Products' => [
'zh' => '牛肉产品',
'en' => 'Beef Products',
'jp' => '牛肉製品',
'fra' => 'Produits de bœuf',
'de' => 'Rindfleischprodukte',
'kor' => '쇠고기 제품',
'ru' => 'Говяжьи продукты',
'pt' => 'Produtos de Carne Bovina',
'spa' => 'Productos de res',
'ara' => 'منتجات لحم البقر'
],
'Beverages' => [
'zh' => '饮料',
'en' => 'Beverages',
'jp' => '飲料',
'fra' => 'Boissons',
'de' => 'Getränke',
'kor' => '음료',
'ru' => 'Напитки',
'pt' => 'Bebidas',
'spa' => 'Bebidas',
'ara' => 'المشروبات'
],
'Finfish and Shellfish Products' => [
'zh' => '鱼类和贝类产品',
'en' => 'Finfish and Shellfish Products',
'jp' => '魚介類製品',
'fra' => 'Poissons et fruits de mer',
'de' => 'Fisch- und Schalentiere',
'kor' => '어류 및 갑각류 제품',
'ru' => 'Рыба и морепродукты',
'pt' => 'Peixes e Frutos do Mar',
'spa' => 'Pescados y mariscos',
'ara' => 'الأسماك والمحار'
],
'Legumes and Legume Products' => [
'zh' => '豆类和豆制品',
'en' => 'Legumes and Legume Products',
'jp' => '豆類と豆製品',
'fra' => 'Légumineuses et produits dérivés',
'de' => 'Hülsenfrüchte und Hülsenfruchtprodukte',
'kor' => '콩류와 콩 제품',
'ru' => 'Бобовые и продукты из них',
'pt' => 'Legumes e Produtos de Legumes',
'spa' => 'Legumbres y productos de legumbres',
'ara' => 'البقوليات ومنتجاتها'
],
'Lamb, Veal, and Game Products' => [
'zh' => '羊肉、小牛肉和野味产品',
'en' => 'Lamb, Veal, and Game Products',
'jp' => '羊肉、子牛肉、ジビエ製品',
'fra' => 'Agneau, veau et gibier',
'de' => 'Lamm, Kalb und Wild',
'kor' => '양고기, 송아지고기, 야생고기 제품',
'ru' => 'Баранина, телятина и дичь',
'pt' => 'Cordeiro, Vitela e Caça',
'spa' => 'Cordero, ternera y caza',
'ara' => 'لحم الضأن والعجل والصيد'
],
'Baked Products' => [
'zh' => '烘焙产品',
'en' => 'Baked Products',
'jp' => '焼き菓子',
'fra' => 'Produits de boulangerie',
'de' => 'Backwaren',
'kor' => '구운 제품',
'ru' => 'Хлебобулочные изделия',
'pt' => 'Produtos Assados',
'spa' => 'Productos horneados',
'ara' => 'المخبوزات'
],
'Sweets' => [
'zh' => '糖果甜点',
'en' => 'Sweets',
'jp' => 'お菓子',
'fra' => 'Sucreries',
'de' => 'Süßigkeiten',
'kor' => '과자',
'ru' => 'Сладости',
'pt' => 'Doces',
'spa' => 'Dulces',
'ara' => 'الحلويات'
],
'Cereal Grains and Pasta' => [
'zh' => '谷物和面食',
'en' => 'Cereal Grains and Pasta',
'jp' => '穀物とパスタ',
'fra' => 'Céréales et pâtes',
'de' => 'Getreide und Nudeln',
'kor' => '곡물과 파스타',
'ru' => 'Зерновые и макаронные изделия',
'pt' => 'Grãos e Massas',
'spa' => 'Cereales y pasta',
'ara' => 'الحبوب والمعكرونة'
],
'Fast Foods' => [
'zh' => '快餐食品',
'en' => 'Fast Foods',
'jp' => 'ファストフード',
'fra' => 'Fast-foods',
'de' => 'Fast Food',
'kor' => '패스트푸드',
'ru' => 'Фастфуд',
'pt' => 'Fast Foods',
'spa' => 'Comida rápida',
'ara' => 'الوجبات السريعة'
],
'Meals, Entrees, and Side Dishes' => [
'zh' => '餐食、主菜和配菜',
'en' => 'Meals, Entrees, and Side Dishes',
'jp' => '食事、メインディッシュ、サイドディッシュ',
'fra' => 'Repas, plats principaux et accompagnements',
'de' => 'Mahlzeiten, Hauptgerichte und Beilagen',
'kor' => '식사, 메인 요리, 사이드 디시',
'ru' => 'Блюда, основные блюда и гарниры',
'pt' => 'Refeições, Pratos Principais e Acompanhamentos',
'spa' => 'Comidas, platos principales y guarniciones',
'ara' => 'الوجبات والأطباق الرئيسية والأطباق الجانبية'
],
'Snacks' => [
'zh' => '零食',
'en' => 'Snacks',
'jp' => 'スナック',
'fra' => 'Snacks',
'de' => 'Snacks',
'kor' => '과자',
'ru' => 'Закуски',
'pt' => 'Lanches',
'spa' => 'Aperitivos',
'ara' => 'الوجبات الخفيفة'
],
'American Indian/Alaska Native Foods' => [
'zh' => '美洲印第安/阿拉斯加原住民食品',
'en' => 'American Indian/Alaska Native Foods',
'jp' => 'アメリカ先住民/アラスカ先住民の食品',
'fra' => 'Aliments amérindiens/autochtones d\'Alaska',
'de' => 'Indianische/alaskische Ureinwohner-Lebensmittel',
'kor' => '아메리카 원주민/알래스카 원주민 음식',
'ru' => 'Пища американских индейцев/коренных жителей Аляски',
'pt' => 'Alimentos dos Nativos Americanos/Alasca',
'spa' => 'Alimentos de nativos americanos/de Alaska',
'ara' => 'أطعمة الأمريكيين الأصليين/سكان ألاسكا الأصليين'
],
'Restaurant Foods' => [
'zh' => '餐厅食品',
'en' => 'Restaurant Foods',
'jp' => 'レストランフード',
'fra' => 'Plats de restaurant',
'de' => 'Restaurantgerichte',
'kor' => '레스토랑 음식',
'ru' => 'Ресторанная еда',
'pt' => 'Comidas de Restaurante',
'spa' => 'Comidas de restaurante',
'ara' => 'أطعمة المطاعم'
],
'Branded Food Products Database' => [
'zh' => '品牌食品数据库',
'en' => 'Branded Food Products Database',
'jp' => 'ブランド食品データベース',
'fra' => 'Base de données de produits alimentaires de marque',
'de' => 'Markenlebensmittel-Datenbank',
'kor' => '브랜드 식품 데이터베이스',
'ru' => 'База данных брендовых продуктов питания',
'pt' => 'Banco de Dados de Produtos Alimentícios Marcados',
'spa' => 'Base de datos de productos alimenticios de marca',
'ara' => 'قاعدة بيانات المنتجات الغذائية ذات العلامات التجارية'
],
'Quality Control Materials' => [
'zh' => '质量控制材料',
'en' => 'Quality Control Materials',
'jp' => '品質管理材料',
'fra' => 'Matériaux de contrôle qualité',
'de' => 'Qualitätskontrollmaterialien',
'kor' => '품질 관리 재료',
'ru' => 'Материалы для контроля качества',
'pt' => 'Materiais de Controle de Qualidade',
'spa' => 'Materiales de control de calidad',
'ara' => 'مواد مراقبة الجودة'
],
'Alcoholic Beverages' => [
'zh' => '酒精饮料',
'en' => 'Alcoholic Beverages',
'jp' => 'アルコール飲料',
'fra' => 'Boissons alcoolisées',
'de' => 'Alkoholische Getränke',
'kor' => '알코올 음료',
'ru' => 'Алкогольные напитки',
'pt' => 'Bebidas Alcoólicas',
'spa' => 'Bebidas alcohólicas',
'ara' => 'المشروبات الكحولية'
]
];
/**
* 猜你喜欢主接口
*/
public function getGuessYouLike($user_id = 1, $type = 'food', $limit = null,$language = 'zh') {
try {
$cfc = Db::connect('cfc_db');
// dump(1);
// 设置限制数量
$tag_limit = $limit ? intval($limit) : $this->config['tag_limit'];
$item_limit = $this->config['item_limit'];
// 检查缓存
// $cache_key = $user_id . ':' . $type;
// $cache_result = $this->getCache($cfc, $cache_key);
// // die;
// if ($cache_result !== null) {
// return $cache_result;
// }
// dump($language);
// 判断用户是否有历史数据
$has_history = $this->checkUserHistory($cfc, $user_id);
if (!$has_history) {
// 新用户,返回最火信息(仅一个标签)
$result = $this->getPopularRecommendations($cfc, $type, 1, $item_limit,$language);
// dump($result);
} else {
// 老用户,根据类型返回个性化推荐
if ($type === 'cookbook') {
// $result = $this->getCookbookRecommendations($cfc, $user_id, $tag_limit, $item_limit,$language);
} else {
$result = $this->getFoodRecommendations($cfc, $user_id, $tag_limit, $item_limit,$language);
}
}
// 确保返回格式正确
if (!is_array($result)) {
$result = [];
}
// 更新缓存
// $this->updateCache($cfc, $cache_key, $user_id, $type, $result);
return $result;
} catch (\Exception $e) {
// 记录错误日志
\think\Log::error('猜你喜欢功能错误: ' . $e->getMessage());
return [];
}
}
/**
* 检查用户是否有历史数据
*/
private function checkUserHistory($db, $user_id) {
try {
// 检查饮食记录
$kcal_result = $db->query("
SELECT COUNT(*) as count
FROM {$this->kitchenscale_db_msg['kcal_log']}
WHERE aud_id = ? AND is_del = 0
", [$user_id]);
$kcal_count = $kcal_result[0]['count'] ?? 0;
// 检查搜索记录
$search_result = $db->query("
SELECT COUNT(*) as count
FROM {$this->kitchenscale_db_msg['search_history']}
WHERE user_id = ? AND is_del = 0
", [$user_id]);
$search_count = $search_result[0]['count'] ?? 0;
return ($kcal_count > 0 || $search_count > 0);
} catch (\Exception $e) {
return false;
}
}
/**
* 获取缓存数据
*/
private function getCache($db, $cache_key) {
try {
$cache_result = $db->query("
SELECT id, cache_key, user_id, keyword, recommend_data, hit_count, last_hit, is_del, create_time
FROM {$this->kitchenscale_db_msg['recommend_cache']}
WHERE cache_key = ? AND is_del = 0
", [$cache_key]);
if (!empty($cache_result)) {
$cache = $cache_result[0];
$last_hit_timestamp = strtotime($cache['last_hit']);
if (time() - $last_hit_timestamp < $this->config['cache_time']) {
// 更新命中次数和时间
$db->execute("
UPDATE {$this->kitchenscale_db_msg['recommend_cache']}
SET hit_count = hit_count + 1, last_hit = GETDATE()
WHERE id = ?
", [$cache['id']]);
$data = json_decode($cache['recommend_data'], true);
return is_array($data) ? $data : null;
}
}
} catch (\Exception $e) {
// 忽略缓存错误,继续执行
}
return null;
}
/**
* 更新缓存
*/
private function updateCache($db, $cache_key, $user_id, $keyword, $data) {
try {
$current_time = date('Y-m-d H:i:s');
$recommend_data = json_encode($data, JSON_UNESCAPED_UNICODE);
// 检查是否存在缓存
$existing_result = $db->query("
SELECT id FROM {$this->kitchenscale_db_msg['recommend_cache']}
WHERE cache_key = ? AND is_del = 0
", [$cache_key]);
if (!empty($existing_result)) {
// 更新现有缓存
$db->execute("
UPDATE {$this->kitchenscale_db_msg['recommend_cache']}
SET user_id = ?, keyword = ?, recommend_data = ?, hit_count = 1,
last_hit = ?, create_time = ?
WHERE cache_key = ? AND is_del = 0
", [$user_id, $keyword, $recommend_data, $current_time, $current_time, $cache_key]);
} else {
// 插入新缓存
$db->execute("
INSERT INTO {$this->kitchenscale_db_msg['recommend_cache']}
(cache_key, user_id, keyword, recommend_data, hit_count, last_hit, create_time, is_del)
VALUES (?, ?, ?, ?, 1, ?, ?, 0)
", [$cache_key, $user_id, $keyword, $recommend_data, $current_time, $current_time]);
}
} catch (\Exception $e) {
// 忽略缓存更新错误
}
}
/**
* 获取热门推荐(新用户)
*/
private function getPopularRecommendations($db, $type, $tag_limit, $item_limit,$language) {
// dump($type);
if ($type === 'cookbook') {
return $this->getPopularCookbooks($db, $tag_limit, $item_limit);
} else {
// dump(111);
return $this->getPopularFoods($db, $tag_limit, $item_limit,$language);
}
}
/**
* 获取热门食谱(新用户)
*/
private function getPopularCookbooks($db, $tag_limit, $item_limit) {
try {
// 简化查询,避免复杂关联导致的错误
$popular_cookbooks = $db->query("
SELECT TOP {$item_limit}
id,
title as name
FROM {$this->kitchenscale_db_msg['cookbook']}
WHERE is_del = 0
ORDER BY likes_num DESC, read_it DESC, create_time DESC
");
// dump('sp');
// dump($popular_cookbooks);
$result = [];
$label_data = [];
foreach ($popular_cookbooks as $cookbook) {
$label_data[] = [
'name' => $cookbook['name'] ?? '未知食谱',
'id' => $cookbook['id'] ?? 0,
'type' => 'cookbook'
];
}
if (!empty($label_data)) {
$result['最火食谱搜索'] = $label_data;
}
return $result;
} catch (\Exception $e) {
return [];
}
}
/**
* 获取热门食材(新用户)
*/
private function getPopularFoods($db, $tag_limit, $item_limit,$language) {
try {
// dump(2222);
// // 简化查询,避免复杂关联导致的错误
$popular_foods = $db->query("
SELECT TOP {$item_limit}
id,
keyword as name,
COUNT(*) as num
FROM {$this->kitchenscale_db_msg['search_history']}
WHERE is_del = 0 AND type = 'food'
GROUP BY id, keyword
ORDER BY num DESC
");
// dump('sc');
// dump($popular_foods);
// dump($language);
if($language == 'zh'){
$language_key = 'food_name';
}else{
if(!$language){
$language_key = 'food_name';
}else{
$language_key = 'food_name_'.$language;
}
}
// dump($language);
$popular_foods_2 = [];
if(count($popular_foods) < $item_limit){
$num = $item_limit - count($popular_foods);
// dump($num);
$popular_foods_2 = $db->query("
SELECT TOP {$num}
id,
$language_key as name
FROM {$this->kitchenscale_db_msg['foodlist3']}
WHERE is_del = 0
ORDER BY is_popular DESC, $language_key ASC
");
}
// dump($popular_foods_2);
foreach ($popular_foods_2 as $key => $value) {
$popular_foods[] = $value;
}
$result = [];
$label_data = [];
foreach ($popular_foods as $food) {
$label_data[] = [
'name' => $food['name'] ?? '????',
'id' => $food['id'] ?? 0,
'type' => 'food'
];
}
if (!empty($label_data)) {
// dump($label_data);
// dump($this->translations[$language]);
if($language){
$result[$this->translations[$language]] = $label_data;
}else{
$result[$this->translations['zh']] = $label_data;
}
}
// dump($result);
// die;
return $result;
} catch (\Exception $e) {
return [];
}
}
/**
* 获取个性化食谱推荐(老用户)
*/
private function getCookbookRecommendations($db, $user_id, $tag_limit, $item_limit) {
try {
// 获取用户最常吃的食材
$user_top_foods = $db->query("
SELECT TOP 10 food_id, COUNT(*) as eat_count
FROM {$this->kitchenscale_db_msg['kcal_log']}
WHERE aud_id = ? AND is_del = 0
GROUP BY food_id
ORDER BY eat_count DESC
", [$user_id]);
if (empty($user_top_foods)) {
return $this->getPopularCookbooks($db, $tag_limit, $item_limit);
}
$food_ids = array_column($user_top_foods, 'food_id');
if (empty($food_ids)) {
return $this->getPopularCookbooks($db, $tag_limit, $item_limit);
}
$food_ids_str = implode(',', $food_ids);
// 获取包含这些食材的食谱标签
$preferred_labels = $db->query("
SELECT TOP {$tag_limit} lbl.id, lbl.name, COUNT(DISTINCT cb.id) as match_count
FROM {$this->kitchenscale_db_msg['cookbook_label']} lbl
INNER JOIN {$this->kitchenscale_db_msg['cookbook']} cb ON lbl.id = cb.cook_label AND cb.is_del = 0
INNER JOIN {$this->kitchenscale_db_msg['cookbook_food_relation']} cfr ON cb.id = cfr.cookbook_id
WHERE lbl.is_del = 0 AND cfr.food_id IN ({$food_ids_str})
GROUP BY lbl.id, lbl.name
ORDER BY match_count DESC
");
$result = [];
foreach ($preferred_labels as $label) {
// 使用子查询避免GROUP BY复杂性问题
$cookbooks = $db->query("
SELECT TOP {$item_limit} cb.id, cb.title as name
FROM {$this->kitchenscale_db_msg['cookbook']} cb
WHERE cb.id IN (
SELECT DISTINCT cfr.cookbook_id
FROM {$this->kitchenscale_db_msg['cookbook_food_relation']} cfr
WHERE cfr.food_id IN ({$food_ids_str})
)
AND cb.cook_label = ?
AND cb.is_del = 0
ORDER BY cb.likes_num DESC, cb.read_it DESC
", [$label['id']]);
$label_data = [];
foreach ($cookbooks as $cookbook) {
$label_data[] = [
'name' => $cookbook['name'] ?? '未知食谱',
'id' => $cookbook['id'] ?? 0,
'type' => 'cookbook'
];
}
if (!empty($label_data)) {
$result[$label['name'] ?? '未知标签'] = $label_data;
}
}
return $result;
} catch (\Exception $e) {
return $this->getPopularCookbooks($db, $tag_limit, $item_limit);
}
}
/**
* 获取个性化食材推荐(老用户)
*/
private function getFoodRecommendations($db, $user_id, $tag_limit, $item_limit,$language) {
try {
// 获取用户最常吃的食材
$user_top_foods = $db->query("
SELECT TOP 10 food_id, COUNT(*) as eat_count
FROM {$this->kitchenscale_db_msg['kcal_log']}
WHERE aud_id = ? AND is_del = 0
GROUP BY food_id
ORDER BY eat_count DESC
", [$user_id]);
// dump($user_id);
// dump($language);
if (empty($user_top_foods)) {
return $this->getPopularFoods($db, $tag_limit, $item_limit,$language);
}
$food_ids = array_column($user_top_foods, 'food_id');
if (empty($food_ids)) {
return $this->getPopularFoods($db, $tag_limit, $item_limit,$language);
}
$food_ids_str = implode(',', $food_ids);
// 获取用户偏好食材的分类
$preferred_categories = $db->query("
SELECT TOP {$tag_limit} f2.id, f2.name, COUNT(DISTINCT f3.id) as food_count
FROM {$this->kitchenscale_db_msg['foodlist2']} f2
INNER JOIN {$this->kitchenscale_db_msg['foodlist3']} f3 ON f2.id = f3.two_id
WHERE f3.id IN ({$food_ids_str}) AND f2.is_del = 0 AND f3.is_del = 0
GROUP BY f2.id, f2.name
ORDER BY food_count DESC
");
$result = [];
if($language == 'zh'){
$language_key = 'food_name';
}else{
if(!$language){
$language = 'zh';
$language_key = 'food_name';
}else{
$language_key = 'food_name_'.$language;
}
}
foreach ($preferred_categories as $category) {
// 获取该分类下的其他食材
$foods = $db->query("
SELECT TOP {$item_limit} id, $language_key as name
FROM {$this->kitchenscale_db_msg['foodlist3']}
WHERE two_id = ? AND is_del = 0 AND id NOT IN ({$food_ids_str})
ORDER BY is_popular DESC, $language_key ASC
", [$category['id']]);
// dump($foods);
$category_data = [];
foreach ($foods as $food) {
$category_data[] = [
'name' => $food['name'] ?? '????',
'id' => $food['id'] ?? 0,
'type' => 'food'
];
}
if (!empty($category_data)) {
$result[$this->food_2_ys[$category['name']][$language] ?? '????'] = $category_data;
}
}
return $result;
} catch (\Exception $e) {
return $this->getPopularFoods($db, $tag_limit, $item_limit,$language);
}
}
}