diff --git a/application/KitchenScale/controller/app/Base.php b/application/KitchenScale/controller/app/Base.php index b423b8c..3d2ee06 100644 --- a/application/KitchenScale/controller/app/Base.php +++ b/application/KitchenScale/controller/app/Base.php @@ -38,9 +38,9 @@ class Base extends Controller{ // 减 bcsub(,,20) // 乘 bcmul(,,20) // 除 bcdiv(,,20) - ################################################################接口################################################################ - ################################################################接口################################################################ - ################################################################接口################################################################ + ################################################################接口监控################################################################ + ################################################################接口监控################################################################ + ################################################################接口监控################################################################ // 接口记录 public function record_api_log($params, $error = null, $response = null){ // dump($params); @@ -62,6 +62,62 @@ class Base extends Controller{ } + + /* 接口说明(发邮件) + * $address(收件人的邮箱地址) 数组 格式: ['460834639@qq.com','460834639@qq.com'.......] + * $content(邮件的主题数据信息) 数组 格式:['title'=>'123','from_user_name'=>'123','content'=>'123'] + * $annex(附件路径信息) 字符串 + */ + public function send_email_api_error($address,$content,$annex=''){ + // $ad = '460834639@qq.com'; + $ad1 = '295155911@qq.com'; + $mail = new PHPMailer(); //实例化 + $mail->IsSMTP(); // 启用SMTP + $mail->Host = "smtp.126.com"; //SMTP服务器 163邮箱例子 + $mail->Port = 465; //邮件发送端口 + $mail->SMTPAuth = true; //启用SMTP认证 + $mail->SMTPSecure = 'ssl'; + $mail->CharSet = "UTF-8"; //字符集 + $mail->Encoding = "base64"; //编码方式 + $mail->Username = "tsf3920322@126.com"; //你的邮箱 + $mail->Password = "HLWXNRPUCTHJFIIX"; //你的密码(邮箱后台的授权密码) + $mail->From = "tsf3920322@126.com"; //发件人地址(也就是你的邮箱) + + // $mail->Subject = "微盟测试邮件"; //邮件标题 + $mail->Subject = $content['title']; //邮件标题 + + // $mail->FromName = "微盟体测中心"; //发件人姓名 + $mail->FromName = $content['from_user_name']; //发件人姓名 + + + for ($i=0; $i < count($address); $i++) { + $mail->AddAddress($address[$i], ""); //添加收件人(地址,昵称) + } + + if($annex != ''){ + // $url = ROOT_PATH. 'public' . DS . 'tsf' . DS .'demoooo.jpg'; + $mail->AddAttachment($annex,''); // 添加附件,并指定名称 + } + + $mail->IsHTML(true); //支持html格式内容 + + $neirong = $content['content']; + + $mail->Body = $neirong; //邮件主体内容 + //发送 + if (!$mail->Send()) { + + return ['code' => 10003,'msg'=>$mail->ErrorInfo]; + // return $mail->ErrorInfo; + } else { + return ['code' => 0]; + // return 'success'; + } + } + + ################################################################通用工具################################################################ + ################################################################通用工具################################################################ + ################################################################通用工具################################################################ // 判断token是否过期 public function token_time_validate($token){ // 591b70e0d80b5fa6d77e6e1384453ab9 @@ -116,60 +172,7 @@ class Base extends Controller{ } } - /* 接口说明(发邮件) - * $address(收件人的邮箱地址) 数组 格式: ['460834639@qq.com','460834639@qq.com'.......] - * $content(邮件的主题数据信息) 数组 格式:['title'=>'123','from_user_name'=>'123','content'=>'123'] - * $annex(附件路径信息) 字符串 - */ - public function send_email_api_error($address,$content,$annex=''){ - // $ad = '460834639@qq.com'; - $ad1 = '295155911@qq.com'; - $mail = new PHPMailer(); //实例化 - $mail->IsSMTP(); // 启用SMTP - $mail->Host = "smtp.126.com"; //SMTP服务器 163邮箱例子 - $mail->Port = 465; //邮件发送端口 - $mail->SMTPAuth = true; //启用SMTP认证 - $mail->SMTPSecure = 'ssl'; - $mail->CharSet = "UTF-8"; //字符集 - $mail->Encoding = "base64"; //编码方式 - $mail->Username = "tsf3920322@126.com"; //你的邮箱 - $mail->Password = "HLWXNRPUCTHJFIIX"; //你的密码(邮箱后台的授权密码) - $mail->From = "tsf3920322@126.com"; //发件人地址(也就是你的邮箱) - - // $mail->Subject = "微盟测试邮件"; //邮件标题 - $mail->Subject = $content['title']; //邮件标题 - - // $mail->FromName = "微盟体测中心"; //发件人姓名 - $mail->FromName = $content['from_user_name']; //发件人姓名 - - - for ($i=0; $i < count($address); $i++) { - $mail->AddAddress($address[$i], ""); //添加收件人(地址,昵称) - } - - if($annex != ''){ - // $url = ROOT_PATH. 'public' . DS . 'tsf' . DS .'demoooo.jpg'; - $mail->AddAttachment($annex,''); // 添加附件,并指定名称 - } - - $mail->IsHTML(true); //支持html格式内容 - - $neirong = $content['content']; - - $mail->Body = $neirong; //邮件主体内容 - //发送 - if (!$mail->Send()) { - - return ['code' => 10003,'msg'=>$mail->ErrorInfo]; - // return $mail->ErrorInfo; - } else { - return ['code' => 0]; - // return 'success'; - } - } - - - // 验证 + // 验证数据类型 public function verify_data_is_ok($data = 2,$type){ if($type == 'str'){ if (is_string($data)) { @@ -225,6 +228,54 @@ class Base extends Controller{ return false; } } + // 计算常规卡路里 + public function count_user_nutrition_all($data){ + // 计算基础代谢率(BMR) + if($data['gender'] == 1){ + // 男性:BMR = 10 × 体重(kg) + 6.25 × 身高(cm) - 5 × 年龄(岁) + 5 + $bmr = bcmul(10,$data['weight'],20); + $bmr = bcadd($bmr,bcmul(6.25,$data['height'],20),20); + $bmr = bcsub($bmr,bcmul(5,$data['age_num'],20),20); + $bmr = bcadd($bmr,5,2); + }else if($data['gender'] == 2){ + // 女性:BMR = 10 × 体重(kg) + 6.25 × 身高(cm) - 5 × 年龄(岁) - 161 + $bmr = bcmul(10,$data['weight'],20); + $bmr = bcadd($bmr,bcmul(6.25,$data['height'],20),20); + $bmr = bcsub($bmr,bcmul(5,$data['age_num'],20),20); + $bmr = bcsub($bmr,161,2); + }else{ + return $this->msg(10003,'性别未知'); + } + + // 每日总能量消耗(TDEE) + // 久坐(很少或没有运动):BMR × 1.2 + // 轻度活动(每周1-3天轻度运动):BMR × 1.375 + // 中度活动(每周3-5天中度运动):BMR × 1.55 + // 高度活动(每周6-7天高强度运动):BMR × 1.725 + // 极高活动(体力劳动或每天高强度训练):BMR × 1.9 + $tdee = bcmul($bmr,1.55,2); + + // 碳水化合物:通常占总热量的45-65% + // 蛋白质:通常占总热量的10-35% + // 脂肪:通常占总热量的20-35% + // 孩子&成年人:碳水化合物50%,蛋白质20%,脂肪30%。 + // 老人:碳水化合物50%,蛋白质25%,脂肪25%。 + // 建议每日摄入量计算: + // 1.碳水化合物(克): (TDEE × 碳水化合物比例) / 4 + // 2.蛋白质(克):(TDEE × 蛋白质比例) / 4 + // 3.脂肪(克): (TDEE × 脂肪比例) / 9 + $carbohydrate = bcdiv(bcmul($tdee,0.5,20),4,2); + if($data['age_num'] < 65){ + $protein = bcdiv(bcmul($tdee,0.2,20),4,2); + $fat = bcdiv(bcmul($tdee,0.3,20),9,2); + }else{ + $protein = bcdiv(bcmul($tdee,0.25,20),4,2); + $fat =bcdiv(bcmul($tdee,0.25,20),9,2); + } + return ['kcal'=>$tdee,'carbohydrate'=>$carbohydrate,'protein'=>$protein,'fat'=>$fat,'bmr'=>$bmr]; + } + ####################################################图片选择上传start############################################################## + ####################################################图片选择上传start############################################################## ####################################################图片选择上传start############################################################## public function pic_chose_list($page = 1) { $data = input(); @@ -344,7 +395,13 @@ class Base extends Controller{ } } ####################################################图片选择上传end############################################################## + ####################################################图片选择上传end############################################################## + ####################################################图片选择上传end############################################################## + + ########################################################其他工具######################################################## + ########################################################其他工具######################################################## + ########################################################其他工具######################################################## public function msg($data,$str='',$result = []){ if(is_array($data)){ if($str != ''){ @@ -374,6 +431,8 @@ class Base extends Controller{ public function ceshi(){ echo 'hello'; } + + } \ No newline at end of file diff --git a/application/KitchenScale/controller/app/Countfood.php b/application/KitchenScale/controller/app/Countfood.php index 17dc8e7..79ce733 100644 --- a/application/KitchenScale/controller/app/Countfood.php +++ b/application/KitchenScale/controller/app/Countfood.php @@ -75,7 +75,7 @@ class Countfood extends Base{ } } // 获取记食器板块内容 - public function get_countfoot_content($data=['token'=>'caadd1be045a65f30b92aa805f1de54a','aud_id'=>1,'time'=>'2025-09-17']){ + public function get_countfoot_content(){ // 尝试捕获异常 // try { if(count(input('post.')) > 0){ @@ -393,14 +393,16 @@ class Countfood extends Base{ $user_data = $cfc->table($this->kitchenscale_db_msg['user']) ->where(["id"=>$data['aud_id']]) - ->field('weight,height,gender,age,is_use_set_kcal,set_kcal') + ->field('weight,height,gender,age,birthday,is_use_set_kcal,set_kcal') ->find(); if(!$user_data){ return $this->msg(10003); } - - $user_data['age_num'] = $user_data['age']; - + if($user_data['birthday']){ + $user_data['age_num'] = $this->calculate_age($user_data['birthday']); + }else{ + $user_data['age_num'] = $user_data['age']; + } $nutrition_data = $this->count_user_nutrition_all($user_data); if($user_data['is_use_set_kcal'] == 1){ // 加 bcadd(,,20) @@ -633,13 +635,13 @@ class Countfood extends Base{ $bz['text'] = '超标'; $bz['color'] = '#FF0000'; } - array_push($return_data,['time'=>$key,'val'=>$value,'unit'=>'kcal','describe'=>$bz['text'],'color'=>$bz['color']]); + array_push($return_data,['time'=>$key,'title'=>'摄入卡路里','val'=>$value,'unit'=>'kcal','describe'=>$bz['text'],'color'=>$bz['color']]); } // dump($return_data); return $this->msg([ - // 'page_now'=>$data['page'], - // 'page_total'=>$page_total, + 'page_now'=>$data['page'], + 'page_total'=>$page_total, 'content_list'=>$return_data ]); } @@ -809,51 +811,51 @@ class Countfood extends Base{ #######################################################################工具####################################################################### #######################################################################工具####################################################################### - public function count_user_nutrition_all($data){ - // 计算基础代谢率(BMR) - if($data['gender'] == 1){ - // 男性:BMR = 10 × 体重(kg) + 6.25 × 身高(cm) - 5 × 年龄(岁) + 5 - $bmr = bcmul(10,$data['weight'],20); - $bmr = bcadd($bmr,bcmul(6.25,$data['height'],20),20); - $bmr = bcsub($bmr,bcmul(5,$data['age_num'],20),20); - $bmr = bcadd($bmr,5,2); - }else if($data['gender'] == 2){ - // 女性:BMR = 10 × 体重(kg) + 6.25 × 身高(cm) - 5 × 年龄(岁) - 161 - $bmr = bcmul(10,$data['weight'],20); - $bmr = bcadd($bmr,bcmul(6.25,$data['height'],20),20); - $bmr = bcsub($bmr,bcmul(5,$data['age_num'],20),20); - $bmr = bcsub($bmr,161,2); - }else{ - return $this->msg(10003,'性别未知'); - } + // public function count_user_nutrition_all($data){ + // // 计算基础代谢率(BMR) + // if($data['gender'] == 1){ + // // 男性:BMR = 10 × 体重(kg) + 6.25 × 身高(cm) - 5 × 年龄(岁) + 5 + // $bmr = bcmul(10,$data['weight'],20); + // $bmr = bcadd($bmr,bcmul(6.25,$data['height'],20),20); + // $bmr = bcsub($bmr,bcmul(5,$data['age_num'],20),20); + // $bmr = bcadd($bmr,5,2); + // }else if($data['gender'] == 2){ + // // 女性:BMR = 10 × 体重(kg) + 6.25 × 身高(cm) - 5 × 年龄(岁) - 161 + // $bmr = bcmul(10,$data['weight'],20); + // $bmr = bcadd($bmr,bcmul(6.25,$data['height'],20),20); + // $bmr = bcsub($bmr,bcmul(5,$data['age_num'],20),20); + // $bmr = bcsub($bmr,161,2); + // }else{ + // return $this->msg(10003,'性别未知'); + // } - // 每日总能量消耗(TDEE) - // 久坐(很少或没有运动):BMR × 1.2 - // 轻度活动(每周1-3天轻度运动):BMR × 1.375 - // 中度活动(每周3-5天中度运动):BMR × 1.55 - // 高度活动(每周6-7天高强度运动):BMR × 1.725 - // 极高活动(体力劳动或每天高强度训练):BMR × 1.9 - $tdee = bcmul($bmr,1.55,2); + // // 每日总能量消耗(TDEE) + // // 久坐(很少或没有运动):BMR × 1.2 + // // 轻度活动(每周1-3天轻度运动):BMR × 1.375 + // // 中度活动(每周3-5天中度运动):BMR × 1.55 + // // 高度活动(每周6-7天高强度运动):BMR × 1.725 + // // 极高活动(体力劳动或每天高强度训练):BMR × 1.9 + // $tdee = bcmul($bmr,1.55,2); - // 碳水化合物:通常占总热量的45-65% - // 蛋白质:通常占总热量的10-35% - // 脂肪:通常占总热量的20-35% - // 孩子&成年人:碳水化合物50%,蛋白质20%,脂肪30%。 - // 老人:碳水化合物50%,蛋白质25%,脂肪25%。 - // 建议每日摄入量计算: - // 1.碳水化合物(克): (TDEE × 碳水化合物比例) / 4 - // 2.蛋白质(克):(TDEE × 蛋白质比例) / 4 - // 3.脂肪(克): (TDEE × 脂肪比例) / 9 - $carbohydrate = bcdiv(bcmul($tdee,0.5,20),4,2); - if($data['age_num'] < 65){ - $protein = bcdiv(bcmul($tdee,0.2,20),4,2); - $fat = bcdiv(bcmul($tdee,0.3,20),9,2); - }else{ - $protein = bcdiv(bcmul($tdee,0.25,20),4,2); - $fat =bcdiv(bcmul($tdee,0.25,20),9,2); - } - return ['kcal'=>$tdee,'carbohydrate'=>$carbohydrate,'protein'=>$protein,'fat'=>$fat,'bmr'=>$bmr]; - } + // // 碳水化合物:通常占总热量的45-65% + // // 蛋白质:通常占总热量的10-35% + // // 脂肪:通常占总热量的20-35% + // // 孩子&成年人:碳水化合物50%,蛋白质20%,脂肪30%。 + // // 老人:碳水化合物50%,蛋白质25%,脂肪25%。 + // // 建议每日摄入量计算: + // // 1.碳水化合物(克): (TDEE × 碳水化合物比例) / 4 + // // 2.蛋白质(克):(TDEE × 蛋白质比例) / 4 + // // 3.脂肪(克): (TDEE × 脂肪比例) / 9 + // $carbohydrate = bcdiv(bcmul($tdee,0.5,20),4,2); + // if($data['age_num'] < 65){ + // $protein = bcdiv(bcmul($tdee,0.2,20),4,2); + // $fat = bcdiv(bcmul($tdee,0.3,20),9,2); + // }else{ + // $protein = bcdiv(bcmul($tdee,0.25,20),4,2); + // $fat =bcdiv(bcmul($tdee,0.25,20),9,2); + // } + // return ['kcal'=>$tdee,'carbohydrate'=>$carbohydrate,'protein'=>$protein,'fat'=>$fat,'bmr'=>$bmr]; + // } public function calculateDateRange($n) { // 获取当前日期和时间 $today = new \DateTime(); diff --git a/application/KitchenScale/controller/app/Guessyoulike.php b/application/KitchenScale/controller/app/Guessyoulike.php new file mode 100644 index 0000000..d249756 --- /dev/null +++ b/application/KitchenScale/controller/app/Guessyoulike.php @@ -0,0 +1,728 @@ + 'app_user_cookbook', + 'cookbook_label' => 'app_user_cookbook_label', + 'foodlist2' => 'app_z_national_standard_food_type_2', + 'foodlist3' => 'app_z_national_standard_food_type_3', + 'kcal_log' => 'app_user_kcal_log', + 'search_log' => 'app_user_search_log', + 'search_history' => 'app_user_search_history', + 'tag_preference' => 'app_user_tag_preference', + 'recommend_cache' => 'app_recommend_cache' + ]; + + protected $config = [ + 'tag_limit' => 5, + 'item_limit' => 8, + 'cache_time' => 3600 + ]; + + /** + * 猜你喜欢主接口 + */ + public function getGuessYouLike($user_id, $input_tags = 'cookbook', $limit = null) { + try { + if (empty($user_id)) { + return ['code' => 0, 'msg' => '用户ID不能为空', 'data' => []]; + } + + if (!in_array($input_tags, ['cookbook', 'food'])) { + return ['code' => 0, 'msg' => '类型参数错误,只能是cookbook或food', 'data' => []]; + } + + $tag_limit = $limit ?: $this->config['tag_limit']; + $item_limit = $this->config['item_limit']; + + $cache_key = $this->generateCacheKey($user_id, $input_tags, $tag_limit); + $cached_result = $this->getCachedRecommendation($cache_key); + + if ($cached_result) { + return $cached_result; + } + + $is_new_user = $this->isNewUser($user_id); + + if ($is_new_user) { + $result = $this->getHotRecommendationsForNewUser($input_tags, $item_limit); + } else { + if ($input_tags === 'cookbook') { + $result = $this->getCookbookRecommendations($user_id, $tag_limit, $item_limit); + } else { + $result = $this->getFoodRecommendations($user_id, $tag_limit, $item_limit); + } + } + + $this->cacheRecommendation($cache_key, $result, $user_id, $input_tags); + + return ['code' => 1, 'msg' => '获取成功', 'data' => $result]; + + } catch (\Exception $e) { + return ['code' => 0, 'msg' => '推荐系统异常: ' . $e->getMessage(), 'data' => []]; + } + } + + /** + * 判断是否是新用户 + */ + private function isNewUser($user_id) { + $cfc = Db::connect('cfc_db'); + + $has_search_history = $cfc->table($this->kitchenscale_db_msg['search_history']) + ->where('user_id', $user_id) + ->where('is_del', 0) + ->count(); + + $has_diet_history = $cfc->table($this->kitchenscale_db_msg['kcal_log']) + ->where('aud_id', $user_id) + ->where('is_del', 0) + ->count(); + + return ($has_search_history + $has_diet_history) == 0; + } + + /** + * 为新用户获取热门推荐(只有一个"热门搜索"标签) + */ + private function getHotRecommendationsForNewUser($input_tags, $item_limit) { + $result = []; + + if ($input_tags === 'cookbook') { + $hot_recipes = $this->getHotRecipes($item_limit); + $result['热门搜索'] = $hot_recipes; + } else { + $hot_foods = $this->getHotFoods($item_limit); + $result['热门搜索'] = $hot_foods; + } + + return $result; + } + + /** + * 获取热门菜谱(基于所有用户的搜索记录和饮食记录) + */ + private function getHotRecipes($limit) { + $cfc = Db::connect('cfc_db'); + + // 方法1:从搜索记录中获取热门菜谱关键词 + $hot_search_keywords = $cfc->table($this->kitchenscale_db_msg['search_history']) + ->where('is_del', 0) + ->group('keyword') + ->order('SUM(search_count) DESC') + ->limit($limit * 2) + ->field('keyword, SUM(search_count) as total_searches') + ->select(); + + $recipes = []; + foreach ($hot_search_keywords as $search_item) { + $keyword = $search_item['keyword']; + + // 查找匹配的菜谱 + $recipe = $cfc->table($this->kitchenscale_db_msg['cookbook']) + ->where("(title LIKE '%".$keyword."%' OR describe_data LIKE '%".$keyword."%') and is_del = 0") + ->field('id, title as name, "cookbook" as type') + ->order('create_time DESC') + ->find(); + + if ($recipe && !in_array($recipe['id'], array_column($recipes, 'id'))) { + $recipes[] = $recipe; + if (count($recipes) >= $limit) break; + } + } + + // 方法2:从饮食记录中分析热门菜谱(通过食材关联) + if (count($recipes) < $limit) { + $remaining = $limit - count($recipes); + + // 获取热门食材 + $hot_foods = $cfc->table($this->kitchenscale_db_msg['kcal_log'] . ' kcal') + ->join($this->kitchenscale_db_msg['foodlist3'] . ' f3', 'kcal.food_id = f3.id') + ->where('kcal.is_del', 0) + ->group('f3.id, f3.name') + ->order('COUNT(*) DESC') + ->limit(10) + ->field('f3.id, f3.name') + ->select(); + + foreach ($hot_foods as $food) { + // 查找包含这些食材的菜谱 + $related_recipes = $cfc->table($this->kitchenscale_db_msg['cookbook']) + ->where("(title LIKE '%".$food['name']."%' OR describe_data LIKE '%".$food['name']."%') and is_del = 0") + ->whereNotIn('id', array_column($recipes, 'id')) + ->field('id, title as name, "cookbook" as type') + ->order('create_time DESC') + ->limit($remaining) + ->select(); + + if ($related_recipes) { + $recipes = array_merge($recipes, $related_recipes); + if (count($recipes) >= $limit) break; + } + } + } + + // 方法3:如果还不够,从菜谱表中按创建时间获取最新的 + if (count($recipes) < $limit) { + $remaining = $limit - count($recipes); + $more_recipes = $cfc->table($this->kitchenscale_db_msg['cookbook']) + ->where('is_del', 0) + ->whereNotIn('id', array_column($recipes, 'id')) + ->field('id, title as name, "cookbook" as type') + ->order('create_time DESC') + ->limit($remaining) + ->select(); + + $recipes = array_merge($recipes, $more_recipes ?: []); + } + + return array_slice($recipes, 0, $limit); + } + + /** + * 获取热门食材(基于所有用户的饮食记录和搜索记录) + */ + private function getHotFoods($limit) { + $cfc = Db::connect('cfc_db'); + + $foods = []; + + // 方法1:从饮食记录中获取热门食材 + $hot_from_diet = $cfc->table($this->kitchenscale_db_msg['kcal_log'] . ' kcal') + ->join($this->kitchenscale_db_msg['foodlist3'] . ' f3', 'kcal.food_id = f3.id') + ->where('kcal.is_del', 0) + ->where('f3.is_del', 0) + ->group('f3.id, f3.name') + ->order('COUNT(*) DESC') + ->limit($limit) + ->field('f3.id, f3.name, "food" as type, COUNT(*) as eat_count') + ->select(); + + if ($hot_from_diet) { + $foods = array_merge($foods, $hot_from_diet); + } + + // 方法2:从搜索记录中获取食材相关关键词 + if (count($foods) < $limit) { + $remaining = $limit - count($foods); + + $food_keywords = $cfc->table($this->kitchenscale_db_msg['search_history']) + ->where('is_del', 0) + ->group('keyword') + ->order('SUM(search_count) DESC') + ->limit($remaining * 2) + ->field('keyword, SUM(search_count) as total_searches') + ->select(); + + foreach ($food_keywords as $keyword_item) { + $keyword = $keyword_item['keyword']; + + // 查找匹配的食材 + $food = $cfc->table($this->kitchenscale_db_msg['foodlist3']) + ->where('name', 'like', '%' . $keyword . '%') + ->where('is_del', 0) + ->whereNotIn('id', array_column($foods, 'id')) + ->field('id, name, "food" as type') + ->find(); + + if ($food) { + $foods[] = $food; + if (count($foods) >= $limit) break; + } + } + } + + // 方法3:如果还不够,从食材表中获取常用食材 + if (count($foods) < $limit) { + $remaining = $limit - count($foods); + $more_foods = $cfc->table($this->kitchenscale_db_msg['foodlist3']) + ->where('is_del', 0) + ->whereNotIn('id', array_column($foods, 'id')) + ->field('id, name, "food" as type') + ->order('id DESC') + ->limit($remaining) + ->select(); + + $foods = array_merge($foods, $more_foods ?: []); + } + + return array_slice($foods, 0, $limit); + } + + /** + * 获取食谱推荐(老用户) + */ + private function getCookbookRecommendations($user_id, $tag_limit, $item_limit) { + $result = []; + + $preferred_tags = $this->getUserCookbookTags($user_id, $tag_limit); + + if (empty($preferred_tags)) { + $preferred_tags = $this->getHotCookbookTags($tag_limit); + } + + foreach ($preferred_tags as $tag_info) { + $tag_name = $tag_info['tag_name']; + $recipes = $this->getRecipesByTag($tag_name, $item_limit); + + if (!empty($recipes)) { + $result[$tag_name] = $recipes; + } + } + + return $result; + } + + /** + * 获取用户食谱标签(基于用户搜索记录和饮食记录) + */ + private function getUserCookbookTags($user_id, $limit) { + $cfc = Db::connect('cfc_db'); + $tags = []; + + // 从用户搜索记录中获取标签 + $user_search_tags = $cfc->table($this->kitchenscale_db_msg['search_history']) + ->where('user_id', $user_id) + ->where('is_del', 0) + ->order('search_count DESC, last_searched_at DESC') + ->limit($limit * 2) + ->field('keyword, search_count') + ->select(); + + foreach ($user_search_tags as $search_item) { + $keyword = $search_item['keyword']; + + // 验证关键词是否对应有效的菜谱标签 + $valid_tag = $cfc->table($this->kitchenscale_db_msg['cookbook_label']) + ->where('label_name', 'like', '%' . $keyword . '%') + ->where('is_del', 0) + ->find(); + + if ($valid_tag) { + $tags[] = [ + 'tag_name' => $valid_tag['label_name'], + 'tag_id' => $valid_tag['id'], + 'source' => 'search', + 'weight' => $search_item['search_count'] + ]; + } + + if (count($tags) >= $limit) break; + } + + // 从用户饮食记录中分析标签(通过食材关联菜谱标签) + if (count($tags) < $limit) { + $user_diet_foods = $cfc->table($this->kitchenscale_db_msg['kcal_log'] . ' kcal') + ->join($this->kitchenscale_db_msg['foodlist3'] . ' f3', 'kcal.food_id = f3.id') + ->where('kcal.aud_id', $user_id) + ->where('kcal.is_del', 0) + ->group('f3.id, f3.name') + ->order('COUNT(*) DESC') + ->limit(5) + ->field('f3.id, f3.name, COUNT(*) as eat_count') + ->select(); + + foreach ($user_diet_foods as $food) { + // 查找包含这些食材的菜谱标签 + $related_tags = $cfc->table($this->kitchenscale_db_msg['cookbook'] . ' c') + ->join($this->kitchenscale_db_msg['cookbook_label'] . ' cl', 'FIND_IN_SET(cl.id, c.cook_label)') + ->where('c.food_ids', 'like', '%"' . $food['id'] . '"%') + ->where('c.is_del', 0) + ->where('cl.is_del', 0) + ->group('cl.id, cl.label_name') + ->order('COUNT(*) DESC') + ->limit(2) + ->field('cl.id, cl.label_name, COUNT(*) as recipe_count') + ->select(); + + foreach ($related_tags as $tag) { + if (!in_array($tag['label_name'], array_column($tags, 'tag_name'))) { + $tags[] = [ + 'tag_name' => $tag['label_name'], + 'tag_id' => $tag['id'], + 'source' => 'diet', + 'weight' => $food['eat_count'] + ]; + } + + if (count($tags) >= $limit) break; + } + + if (count($tags) >= $limit) break; + } + } + + // 按权重排序 + usort($tags, function($a, $b) { + return $b['weight'] <=> $a['weight']; + }); + + return array_slice($tags, 0, $limit); + } + + /** + * 获取热门食谱标签(基于所有用户数据) + */ + private function getHotCookbookTags($limit) { + $cfc = Db::connect('cfc_db'); + + // 从搜索记录中分析热门标签 + $hot_search_tags = $cfc->table($this->kitchenscale_db_msg['search_history']) + ->where('is_del', 0) + ->group('keyword') + ->order('SUM(search_count) DESC') + ->limit($limit * 2) + ->field('keyword, SUM(search_count) as total_searches') + ->select(); + + $tags = []; + foreach ($hot_search_tags as $search_item) { + $keyword = $search_item['keyword']; + + $valid_tag = $cfc->table($this->kitchenscale_db_msg['cookbook_label']) + ->where('label_name', 'like', '%' . $keyword . '%') + ->where('is_del', 0) + ->find(); + + if ($valid_tag && !in_array($valid_tag['label_name'], array_column($tags, 'tag_name'))) { + $tags[] = [ + 'tag_name' => $valid_tag['label_name'], + 'tag_id' => $valid_tag['id'], + 'search_count' => $search_item['total_searches'] + ]; + } + + if (count($tags) >= $limit) break; + } + + // 如果不够,从标签表中获取 + if (count($tags) < $limit) { + $remaining = $limit - count($tags); + $more_tags = $cfc->table($this->kitchenscale_db_msg['cookbook_label']) + ->where('is_del', 0) + ->whereNotIn('id', array_column($tags, 'tag_id')) + ->field('id, label_name as tag_name') + ->order('id DESC') + ->limit($remaining) + ->select(); + + $tags = array_merge($tags, $more_tags ?: []); + } + + return array_slice($tags, 0, $limit); + } + + /** + * 根据标签获取食谱 + */ + private function getRecipesByTag($tag_name, $limit) { + $cfc = Db::connect('cfc_db'); + + $recipes = $cfc->table($this->kitchenscale_db_msg['cookbook'] . ' c') + ->join($this->kitchenscale_db_msg['cookbook_label'] . ' cl', 'FIND_IN_SET(cl.id, c.cook_label)') + ->where('cl.label_name', 'like', '%' . $tag_name . '%') + ->where('c.is_del', 0) + ->where('cl.is_del', 0) + ->field('c.id, c.title as name, "cookbook" as type') + ->order('c.create_time DESC') + ->limit($limit) + ->select(); + + return $recipes ?: []; + } + + /** + * 获取食材推荐(老用户) + */ + private function getFoodRecommendations($user_id, $tag_limit, $item_limit) { + $result = []; + + $preferred_categories = $this->getUserFoodCategories($user_id, $tag_limit); + + if (empty($preferred_categories)) { + $preferred_categories = $this->getHotFoodCategories($tag_limit); + } + + foreach ($preferred_categories as $category_info) { + $category_name = $category_info['category_name']; + $foods = $this->getFoodsByCategory($category_info['category_id'], $item_limit); + + if (!empty($foods)) { + $result[$category_name] = $foods; + } + } + + return $result; + } + + /** + * 获取用户食材分类(基于用户饮食记录) + */ + private function getUserFoodCategories($user_id, $limit) { + $cfc = Db::connect('cfc_db'); + $categories = []; + + $diet_categories = $cfc->table($this->kitchenscale_db_msg['kcal_log'] . ' kcal') + ->join($this->kitchenscale_db_msg['foodlist3'] . ' f3', 'kcal.food_id = f3.id') + ->join($this->kitchenscale_db_msg['foodlist2'] . ' f2', 'f3.two_id = f2.id') + ->where('kcal.aud_id', $user_id) + ->where('kcal.is_del', 0) + ->group('f2.id, f2.name') + ->order('COUNT(*) DESC') + ->limit($limit) + ->field('f2.id as category_id, f2.name as category_name, COUNT(*) as eat_count') + ->select(); + + foreach ($diet_categories as $category) { + $categories[] = [ + 'category_id' => $category['category_id'], + 'category_name' => $category['category_name'], + 'eat_count' => $category['eat_count'] + ]; + } + + return array_slice($categories, 0, $limit); + } + + /** + * 获取热门食材分类(基于所有用户数据) + */ + private function getHotFoodCategories($limit) { + $cfc = Db::connect('cfc_db'); + + // 从饮食记录中分析热门分类 + $hot_categories = $cfc->table($this->kitchenscale_db_msg['kcal_log'] . ' kcal') + ->join($this->kitchenscale_db_msg['foodlist3'] . ' f3', 'kcal.food_id = f3.id') + ->join($this->kitchenscale_db_msg['foodlist2'] . ' f2', 'f3.two_id = f2.id') + ->where('kcal.is_del', 0) + ->group('f2.id, f2.name') + ->order('COUNT(*) DESC') + ->limit($limit) + ->field('f2.id as category_id, f2.name as category_name, COUNT(*) as total_eat_count') + ->select(); + + if ($hot_categories && count($hot_categories) >= $limit) { + return $hot_categories; + } + + // 如果不够,从分类表中获取 + $categories = $hot_categories ?: []; + if (count($categories) < $limit) { + $remaining = $limit - count($categories); + $more_categories = $cfc->table($this->kitchenscale_db_msg['foodlist2']) + ->where('is_del', 0) + ->whereNotIn('id', array_column($categories, 'category_id')) + ->field('id as category_id, name as category_name') + ->order('id DESC') + ->limit($remaining) + ->select(); + + $categories = array_merge($categories, $more_categories ?: []); + } + + return array_slice($categories, 0, $limit); + } + + /** + * 根据分类获取食材 + */ + private function getFoodsByCategory($category_id, $limit) { + $cfc = Db::connect('cfc_db'); + + $foods = $cfc->table($this->kitchenscale_db_msg['foodlist3']) + ->where('two_id', $category_id) + ->where('is_del', 0) + ->field('id, name, "food" as type') + ->order('id DESC') + ->limit($limit) + ->select(); + + return $foods ?: []; + } + + /** + * 生成缓存key + */ + private function generateCacheKey($user_id, $input_tags, $tag_limit) { + return $user_id . ':' . $input_tags . ':' . $tag_limit; + } + + /** + * 获取缓存推荐 + */ + private function getCachedRecommendation($cache_key) { + $cfc = Db::connect('cfc_db'); + + $cache = $cfc->table($this->kitchenscale_db_msg['recommend_cache']) + ->where('cache_key', $cache_key) + ->where('is_del', 0) + ->where('last_hit', '>=', date('Y-m-d H:i:s', time() - $this->config['cache_time'])) + ->find(); + + if ($cache) { + $cfc->table($this->kitchenscale_db_msg['recommend_cache']) + ->where('id', $cache['id']) + ->update([ + 'hit_count' => $cache['hit_count'] + 1, + 'last_hit' => date('Y-m-d H:i:s') + ]); + + return json_decode($cache['recommend_data'], true); + } + + return null; + } + + /** + * 缓存推荐结果 + */ + private function cacheRecommendation($cache_key, $data, $user_id, $input_tags) { + $cfc = Db::connect('cfc_db'); + + $cache_data = [ + 'cache_key' => $cache_key, + 'user_id' => $user_id, + 'keyword' => $input_tags, + 'recommend_data' => json_encode($data, JSON_UNESCAPED_UNICODE), + 'hit_count' => 1, + 'last_hit' => date('Y-m-d H:i:s'), + 'create_time' => date('Y-m-d H:i:s') + ]; + + $cfc->table($this->kitchenscale_db_msg['recommend_cache']) + ->insert($cache_data); + } + + /** + * 记录用户标签点击(用于更新偏好权重) + */ + public function recordTagClick($user_id, $tag_name, $tag_type) { + try { + $cfc = Db::connect('cfc_db'); + + $preference = $cfc->table($this->kitchenscale_db_msg['tag_preference']) + ->where('user_id', $user_id) + ->where('tag_name', $tag_name) + ->where('tag_type', $tag_type) + ->where('is_del', 0) + ->find(); + + if ($preference) { + $new_weight = min($preference['preference_weight'] + 1, 10); + $cfc->table($this->kitchenscale_db_msg['tag_preference']) + ->where('id', $preference['id']) + ->update([ + 'preference_weight' => $new_weight, + 'last_updated' => date('Y-m-d H:i:s') + ]); + } else { + $cfc->table($this->kitchenscale_db_msg['tag_preference']) + ->insert([ + 'user_id' => $user_id, + 'tag_type' => $tag_type, + 'tag_name' => $tag_name, + 'tag_id' => 0, + 'preference_weight' => 1, + 'create_time' => date('Y-m-d H:i:s'), + 'last_updated' => date('Y-m-d H:i:s') + ]); + } + + return true; + } catch (\Exception $e) { + return false; + } + } + + /** + * 清除用户推荐缓存 + */ + public function clearUserCache($user_id) { + try { + $cfc = Db::connect('cfc_db'); + + $cfc->table($this->kitchenscale_db_msg['recommend_cache']) + ->where('user_id', $user_id) + ->update(['is_del' => 1]); + + return true; + } catch (\Exception $e) { + return false; + } + } + + /** + * 获取推荐统计信息 + */ + public function getRecommendStats($user_id) { + $cfc = Db::connect('cfc_db'); + + $cache_stats = $cfc->table($this->kitchenscale_db_msg['recommend_cache']) + ->where('user_id', $user_id) + ->where('is_del', 0) + ->field('COUNT(*) as cache_count, SUM(hit_count) as total_hits') + ->find(); + + $preference_stats = $cfc->table($this->kitchenscale_db_msg['tag_preference']) + ->where('user_id', $user_id) + ->where('is_del', 0) + ->field('COUNT(*) as tag_count, AVG(preference_weight) as avg_weight') + ->find(); + + return [ + 'cache_count' => $cache_stats['cache_count'] ?? 0, + 'total_hits' => $cache_stats['total_hits'] ?? 0, + 'tag_count' => $preference_stats['tag_count'] ?? 0, + 'avg_weight' => round($preference_stats['avg_weight'] ?? 0, 2) + ]; + } + + /** + * 测试方法 + */ + public function test() { + $user_id = 1; + + // 测试新用户食谱推荐 + $result1 = $this->getGuessYouLike($user_id, 'cookbook'); + + // 测试新用户食材推荐 + $result2 = $this->getGuessYouLike($user_id, 'food'); + + // 自定义数量 + $result3 = $this->getGuessYouLike($user_id, 'cookbook', 3); + + // 记录标签点击 + $this->recordTagClick($user_id, '家常菜', 'cookbook_label'); + + // 获取统计信息 + $stats = $this->getRecommendStats($user_id); + + return [ + 'cookbook_result' => $result1, + 'food_result' => $result2, + 'custom_limit' => $result3, + 'stats' => $stats + ]; + } + + /** + * 成功返回方法 + */ + private function success($msg, $data = []) { + return ['code' => 1, 'msg' => $msg, 'data' => $data]; + } + + /** + * 错误返回方法 + */ + private function error($msg) { + return ['code' => 0, 'msg' => $msg, 'data' => []]; + } +} \ No newline at end of file diff --git a/application/KitchenScale/controller/app/Index.php b/application/KitchenScale/controller/app/Index.php index 1d9b717..a59399a 100644 --- a/application/KitchenScale/controller/app/Index.php +++ b/application/KitchenScale/controller/app/Index.php @@ -25,7 +25,15 @@ class Index extends Base{ 'collect_list'=>'app_user_collect_list',//点赞表 'banner'=>'app_banner_data',//banner 'version'=>'app_version_log',//版本表 - 'user'=>'app_user_data',//banner + 'user'=>'app_user_data',//用户表 + 'kcal_log'=>'app_user_kcal_log',//饮食记录表 + 'search_log'=>'app_user_search_log',//搜索历史表 + + ]; + + protected $reedaw_db_name = [ + 'banner'=>'admin_notice_banner',//菜谱表 + ]; @@ -157,33 +165,31 @@ class Index extends Base{ } // 获取默认配置信息(包含:食材的分类列表,用户角色信息)(OK) - public function get_default_config($data = ['token'=>'']){ - try { - if(count(input('post.')) > 0){ - $data = input('post.'); + public function get_default_config(){ + // try { + $data = input('post.'); + if(!array_key_exists('token', $data)){ + return $this->msg(10001); + } + if(!$this->verify_data_is_ok($data['token'],'str')){ + return $this->msg(10005); } - // if(!array_key_exists('token', $data)){ - // return $this->msg(10001); - // } - // if(!$this->verify_data_is_ok($data['token'],'str')){ - // return $this->msg(10005); - // } $return_data = $this->get_default_config_action($data); return $return_data; - } catch (\Exception $e) { - // 捕获异常 - $logContent["flie"] = $e->getFile(); - $logContent["line"] = $e->getLine(); - $logContent['all_content'] = "异常信息:\n"; - $logContent['all_content'] .= "消息: " . $e->getMessage() . "\n"; - $logContent['all_content'] .= "接口: (get_default_config)\n"; - $logContent['all_content'] .= "代码: " . $e->getCode() . "\n"; - $logContent['all_content'] .= "文件: " . $e->getFile() . "\n"; - $logContent['all_content'] .= "行号: " . $e->getLine() . "\n"; - $logContent['all_content'] .= "跟踪信息:\n" . $e->getTraceAsString() . "\n"; - $this->record_api_log($data, $logContent, null); - return $this->msg(99999); - } + // } catch (\Exception $e) { + // // 捕获异常 + // $logContent["flie"] = $e->getFile(); + // $logContent["line"] = $e->getLine(); + // $logContent['all_content'] = "异常信息:\n"; + // $logContent['all_content'] .= "消息: " . $e->getMessage() . "\n"; + // $logContent['all_content'] .= "接口: (get_default_config)\n"; + // $logContent['all_content'] .= "代码: " . $e->getCode() . "\n"; + // $logContent['all_content'] .= "文件: " . $e->getFile() . "\n"; + // $logContent['all_content'] .= "行号: " . $e->getLine() . "\n"; + // $logContent['all_content'] .= "跟踪信息:\n" . $e->getTraceAsString() . "\n"; + // $this->record_api_log($data, $logContent, null); + // return $this->msg(99999); + // } } // 首页搜索接口(OK) @@ -227,55 +233,123 @@ class Index extends Base{ #######################################################################action####################################################################### #######################################################################action####################################################################### + // 老版 + // public function get_default_config_action($data){ + // $return_data = [ + // 'cook_label'=>[], + // // 'account'=>[], + // 'food_list'=>[], + // 'banner'=>[], + // 'jingang_region'=>[ + // ['name'=>'菜谱分类','jump_url'=>'/pages/menu/menu','icon'=>'https://tc.pcxbc.com/kitchenscale_all/vajra1.png'], + // ['name'=>'我的收藏','jump_url'=>'/pageTwo/me/mymenu','icon'=>'https://tc.pcxbc.com/kitchenscale_all/vajra2.png'], + // ['name'=>'热量计算','jump_url'=>'/pages/count/count','icon'=>'https://tc.pcxbc.com/kitchenscale_all/vajra3.png'], + // ['name'=>'健康食谱','jump_url'=>'/pages/menu/menu','icon'=>'https://tc.pcxbc.com/kitchenscale_all/vajra4.png'], + // ], + // ]; + + // $cfc = Db::connect('cfc_db'); + // // // 获取食材分类列表start + // // $foodlist1 = $cfc->table($this->kitchenscale_db_msg['foodlist1'])->where("is_del = 0")->order('sort_num desc')->field('id,name')->select(); + + // $foodlist1 = $cfc->query("SELECT id,name FROM ".$this->kitchenscale_db_msg['foodlist1']." WHERE is_del = 0 ORDER BY sort_num"); + // // dump($foodlist1); + // // die; + // $foodlist2 = $cfc->table($this->kitchenscale_db_msg['foodlist2'])->where("is_del = 0")->field('id,name,one_id')->select(); + // // dump($foodlist3); + // foreach ($foodlist1 as $key => $value) { + // unset($foodlist1[$key]['ROW_NUMBER']); + // $foodlist1[$key]['list'] = []; + // foreach ($foodlist2 as $k => $v) { + // if($v['one_id'] == $value['id']){ + // unset($foodlist2[$k]['ROW_NUMBER']); + // array_push($foodlist1[$key]['list'],$foodlist2[$k]); + // // unset($foodlist2[$k]); + // } + // } + // } + // $return_data['food_list'] = $foodlist1; + // // // 获取食材分类列表end + // // 获取菜谱分类标签start + // $cook_label = $cfc->table($this->kitchenscale_db_msg['cookbook_label']) + // ->where("is_del = 0") + // ->field('id,name') + // ->select(); + // foreach ($cook_label as $key => $value) { + // unset($cook_label[$key]['ROW_NUMBER']); + // } + // $return_data['cook_label'] = $cook_label; + // // 获取菜谱分类标签end + + // // 获取首页信息start + // // 获取banner + // $banner_list = $cfc->query("select b.id,b.title,b.cover,b.create_user_head_pic,b.create_user_nickname,c.pic_url + // from ".$this->kitchenscale_db_msg['banner']." as a + // LEFT JOIN ".$this->kitchenscale_db_msg['cookbook']." as b on a.cookbook_id = b.id + // LEFT JOIN ".$this->kitchenscale_db_msg['uploadimg']." as c on b.cover = c.id + // where a.is_del=0 AND b.is_del=0 + // ORDER BY a.sort_num desc,a.id desc + // "); + // // dump($banner_list); + // // die; + // if($data['token'] != ''){ + // // 获取账号下信息以及用户信息 + // $user_data = Db::table($this->reedaw_db_msg['zhanghao'])->where(['token'=>$data['token']])->field('id,token,nickname,head_pic,tel,email')->find(); + // if(!$user_data){ + // return $this->msg(20001,'账号信息错误'); + // } + // if(!$this->verify_data_is_ok($data['token'],'str')){ + // return $this->msg(10005); + // } + // // 获取账号下信息以及用户信息 + // $user_data = Db::table($this->reedaw_db_msg['zhanghao'])->where(['token'=>$data['token']])->field('id,token,nickname,head_pic')->find(); + // if(!$user_data){ + // return $this->msg(20001,'账号信息错误'); + // } + // $collect_list = $cfc->table($this->kitchenscale_db_msg['collect_list'])->where(['token'=>$data['token'],'is_del'=>0])->column('cookbook_id'); + // foreach ($banner_list as $key => $value) { + // if(array_key_exists($value['id'],$collect_list)){ + // $banner_list[$key]['is_me_like_it'] = 'yes'; + // }else{ + // $banner_list[$key]['is_me_like_it'] = 'no'; + // } + // unset($banner_list[$key]['ROW_NUMBER']); + // } + // }else{ + // foreach ($banner_list as $key => $value) { + // $banner_list[$key]['is_me_like_it'] = 'no'; + // unset($banner_list[$key]['ROW_NUMBER']); + // } + // } + // $return_data['banner'] = $banner_list; + // // return $this->msg($return_data); + // // 获取首页信息end + // return $this->msg($return_data); + // } + // 新版 public function get_default_config_action($data){ - $return_data = [ - 'cook_label'=>[], - // 'account'=>[], - 'food_list'=>[], - 'banner'=>[], - 'jingang_region'=>[ - ['name'=>'菜谱分类','jump_url'=>'/pages/menu/menu','icon'=>'https://tc.pcxbc.com/kitchenscale_all/vajra1.png'], - ['name'=>'我的收藏','jump_url'=>'/pageTwo/me/mymenu','icon'=>'https://tc.pcxbc.com/kitchenscale_all/vajra2.png'], - ['name'=>'热量计算','jump_url'=>'/pages/count/count','icon'=>'https://tc.pcxbc.com/kitchenscale_all/vajra3.png'], - ['name'=>'健康食谱','jump_url'=>'/pages/menu/menu','icon'=>'https://tc.pcxbc.com/kitchenscale_all/vajra4.png'], + 'user_data'=>[], + 'kcal_data'=>[ + 'title'=>'今日已摄入热量(千卡)', + 'kcal'=>['value'=>0,'unit'=>'kcal','standard'=>'不达标','color'=>'#F0AD4E'], + 'other_elements'=>[ + 'carbohydrate'=>['value'=>0,'unit'=>'g'], + 'protein'=>['value'=>0,'unit'=>'g'], + 'fat'=>['value'=>0,'unit'=>'g'], + ], + 'list'=>[ + ['title'=>'早餐(千卡)','icon'=>'','value'=>0,'unit'=>'kcal'], + ['title'=>'午餐(千卡)','icon'=>'','value'=>0,'unit'=>'kcal'], + ['title'=>'晚餐(千卡)','icon'=>'','value'=>0,'unit'=>'kcal'], + ['title'=>'加餐(千卡)','icon'=>'','value'=>0,'unit'=>'kcal'], + ], ], + 'banner_data'=>[], + 'search_history'=>[], + 'search_guess'=>[], ]; - $cfc = Db::connect('cfc_db'); - // // 获取食材分类列表start - // $foodlist1 = $cfc->table($this->kitchenscale_db_msg['foodlist1'])->where("is_del = 0")->order('sort_num desc')->field('id,name')->select(); - - $foodlist1 = $cfc->query("SELECT id,name FROM ".$this->kitchenscale_db_msg['foodlist1']." WHERE is_del = 0 ORDER BY sort_num"); - // dump($foodlist1); - // die; - $foodlist2 = $cfc->table($this->kitchenscale_db_msg['foodlist2'])->where("is_del = 0")->field('id,name,one_id')->select(); - // dump($foodlist3); - foreach ($foodlist1 as $key => $value) { - unset($foodlist1[$key]['ROW_NUMBER']); - $foodlist1[$key]['list'] = []; - foreach ($foodlist2 as $k => $v) { - if($v['one_id'] == $value['id']){ - unset($foodlist2[$k]['ROW_NUMBER']); - array_push($foodlist1[$key]['list'],$foodlist2[$k]); - // unset($foodlist2[$k]); - } - } - } - $return_data['food_list'] = $foodlist1; - // // 获取食材分类列表end - // 获取菜谱分类标签start - $cook_label = $cfc->table($this->kitchenscale_db_msg['cookbook_label']) - ->where("is_del = 0") - ->field('id,name') - ->select(); - foreach ($cook_label as $key => $value) { - unset($cook_label[$key]['ROW_NUMBER']); - } - $return_data['cook_label'] = $cook_label; - // 获取菜谱分类标签end - - // 获取首页信息start // 获取banner $banner_list = $cfc->query("select b.id,b.title,b.cover,b.create_user_head_pic,b.create_user_nickname,c.pic_url from ".$this->kitchenscale_db_msg['banner']." as a @@ -284,43 +358,106 @@ class Index extends Base{ where a.is_del=0 AND b.is_del=0 ORDER BY a.sort_num desc,a.id desc "); - // dump($banner_list); - // die; + // 如果有账号信息 if($data['token'] != ''){ - // 获取账号下信息以及用户信息 - $user_data = Db::table($this->reedaw_db_msg['zhanghao'])->where(['token'=>$data['token']])->field('id,token,nickname,head_pic,tel,email')->find(); - if(!$user_data){ - return $this->msg(20001,'账号信息错误'); - } if(!$this->verify_data_is_ok($data['token'],'str')){ return $this->msg(10005); } - // 获取账号下信息以及用户信息 - $user_data = Db::table($this->reedaw_db_msg['zhanghao'])->where(['token'=>$data['token']])->field('id,token,nickname,head_pic')->find(); - if(!$user_data){ + // 获取账号下信息以及用户信息 start + $user = $cfc->table($this->kitchenscale_db_msg['user'])->where(["token"=>$data['token']])->find(); + if(!$user){ return $this->msg(20001,'账号信息错误'); } - $collect_list = $cfc->table($this->kitchenscale_db_msg['collect_list'])->where(['token'=>$data['token'],'is_del'=>0])->column('cookbook_id'); - foreach ($banner_list as $key => $value) { - if(array_key_exists($value['id'],$collect_list)){ - $banner_list[$key]['is_me_like_it'] = 'yes'; - }else{ - $banner_list[$key]['is_me_like_it'] = 'no'; + $return_data['user_data'] = $user; + if($return_data['user_data']['birthday']){ + $return_data['user_data']['age'] = $this->calculate_age($return_data['user_data']['birthday']); + } + unset($return_data['user_data']['id']); + unset($return_data['user_data']['token']); + unset($return_data['user_data']['update_time']); + unset($return_data['user_data']['ROW_NUMBER']); + // 获取账号下信息以及用户信息 end + // 处理计食器信息 start + $kcal = $cfc->table($this->kitchenscale_db_msg['kcal_log'])->where(["aud_id"=>$user['id'],'is_del'=>0])->whereTime('create_time', 'today')->order('id desc')->select(); + if(count($kcal)>0){ + $return_data['kcal_data']['title'] = '今日已摄入热量(千卡)'.$kcal[0]['create_time']; + foreach ($kcal as $key => $value) { + + $return_data['kcal_data']['kcal']['value'] = bcadd($return_data['kcal_data']['kcal']['value'],$value['kcal_val'],2); + $return_data['kcal_data']['other_elements']['carbohydrate']['value'] = bcadd($return_data['kcal_data']['other_elements']['carbohydrate']['value'],$value['carbohydrate_val'],2); + $return_data['kcal_data']['other_elements']['protein']['value'] = bcadd($return_data['kcal_data']['other_elements']['protein']['value'],$value['protein_val'],2); + $return_data['kcal_data']['other_elements']['fat']['value'] = bcadd($return_data['kcal_data']['other_elements']['fat']['value'],$value['fat_val'],2); + if($value['meals_type'] == '早餐'){ + $return_data['kcal_data']['list'][0]['value'] = bcadd($return_data['kcal_data']['list'][0]['value'],$value['kcal_val'],2); + }else if($value['meals_type'] == '午餐'){ + $return_data['kcal_data']['list'][1]['value'] = bcadd($return_data['kcal_data']['list'][1]['value'],$value['kcal_val'],2); + }else if($value['meals_type'] == '晚餐'){ + $return_data['kcal_data']['list'][2]['value'] = bcadd($return_data['kcal_data']['list'][2]['value'],$value['kcal_val'],2); + }else{ + $return_data['kcal_data']['list'][3]['value'] = bcadd($return_data['kcal_data']['list'][3]['value'],$value['kcal_val'],2); + } + } + foreach ($return_data['kcal_data']['list'] as $key => $value) { + if($value['value'] <= 0){ + $return_data['kcal_data']['list'][$key]['value'] = '-'; + } } - unset($banner_list[$key]['ROW_NUMBER']); } + + if($user['is_use_set_kcal'] == 1){ + $nutrition_data['kcal'] = $user['set_kcal']; + }else{ + $user['age_num'] = $return_data['user_data']['age']; + $nutrition_data = $this->count_user_nutrition_all($user); + } + + if(bcdiv($return_data['kcal_data']['kcal']['value'],$nutrition_data['kcal'],2) < 0.9){ + $return_data['kcal_data']['kcal']['standard'] = '不达标'; + $return_data['kcal_data']['kcal']['color'] = '#F0AD4E'; + }else if(bcdiv($return_data['kcal_data']['kcal']['value'],$nutrition_data['kcal'],2) >= 0.9 && bcdiv($return_data['kcal_data']['kcal']['value'],$nutrition_data['kcal'],2) < 1.1){ + $return_data['kcal_data']['kcal']['standard'] = '达标'; + $return_data['kcal_data']['kcal']['color'] = '#4CD964'; + }else{ + $return_data['kcal_data']['kcal']['standard'] = '超标'; + $return_data['kcal_data']['kcal']['color'] = '#FF0000'; + } + // 处理计食器信息 end + + // 处理搜索历史 start + $search_log = $cfc->table($this->kitchenscale_db_msg['search_log'])->where(["aud_id"=>$user['id'],'is_del'=>0])->order('id desc')->limit(30)->select(); + + $return_data['search_history'] = $search_log; + // 处理搜索历史 end }else{ - foreach ($banner_list as $key => $value) { - $banner_list[$key]['is_me_like_it'] = 'no'; - unset($banner_list[$key]['ROW_NUMBER']); - } + // foreach ($banner_list as $key => $value) { + // $banner_list[$key]['is_me_like_it'] = 'no'; + // unset($banner_list[$key]['ROW_NUMBER']); + // } } - $return_data['banner'] = $banner_list; - // return $this->msg($return_data); - // 获取首页信息end + // 处理banner信息 start + // $collect_list = $cfc->table($this->kitchenscale_db_msg['collect_list'])->where(['token'=>$data['token'],'is_del'=>0])->column('cookbook_id'); + // foreach ($banner_list as $key => $value) { + // if(array_key_exists($value['id'],$collect_list)){ + // $banner_list[$key]['is_me_like_it'] = 'yes'; + // }else{ + // $banner_list[$key]['is_me_like_it'] = 'no'; + // } + // unset($banner_list[$key]['ROW_NUMBER']); + // } + $banner_list = Db::table($this->reedaw_db_name['banner'])->where(['scene_data' => '3','is_del'=>0])->cache(3600)->order('sort_num desc')->field('id,type,pic,jump_url,parameter_data,sort_num')->select(); + for ($i=0; $i < count($banner_list); $i++) { + if($banner_list[$i]['type'] != 1){ + $banner_list[$i]['parameter_data'] = ''; + } + unset($banner_list[$i]['sort_num']); + unset($banner_list[$i]['ROW_NUMBER']); + } + // 处理banner信息 end + $return_data['banner_data'] = $banner_list; + + return $this->msg($return_data); } - public function search_column_action($data){ diff --git a/application/KitchenScale/controller/app/Usercenter.php b/application/KitchenScale/controller/app/Usercenter.php index 7437243..7806ae4 100644 --- a/application/KitchenScale/controller/app/Usercenter.php +++ b/application/KitchenScale/controller/app/Usercenter.php @@ -65,7 +65,7 @@ class Usercenter extends Base{ } } // 修改用户 - public function update_user_msg($data = ['token'=>'caadd1be045a65f30b92aa805f1de54a','nickname'=>'测试人员001','gender'=>'1','age'=>'18','height'=>'165.34','weight'=>'55.55']){ + public function update_user_msg(){ try { if(count(input('post.')) > 0){ $data = input('post.'); @@ -79,8 +79,8 @@ class Usercenter extends Base{ if(!array_key_exists('gender', $data)){ return $this->msg(10001,'gender is miss'); } - if(!array_key_exists('age', $data)){ - return $this->msg(10001,'age is miss'); + if(!array_key_exists('birthday', $data)){ + return $this->msg(10001,'birthday is miss'); } if(!array_key_exists('height', $data)){ return $this->msg(10001,'height is miss'); @@ -97,8 +97,8 @@ class Usercenter extends Base{ if(!$this->verify_data_is_ok($data['gender'],'intnum')){ return $this->msg(10005,'gender type is error'); } - if(!$this->verify_data_is_ok($data['age'],'intnum')){ - return $this->msg(10005,'age type is error'); + if(!$this->verify_data_is_ok($data['birthday'],'datetime')){ + return $this->msg(10005,'birthday type is error'); } if(!$this->verify_data_is_ok($data['height'],'num')){ return $this->msg(10005,'height type is error'); @@ -305,7 +305,7 @@ class Usercenter extends Base{ $user_msg['nickname'] = $data['nickname']; $user_msg['head_pic'] = $data['gender'] == 1?'https://tc.pcxbc.com/tsf/1.png':'https://tc.pcxbc.com/tsf/2.png'; $user_msg['gender'] = $data['gender']; - $user_msg['age'] = $data['age']; + $user_msg['birthday'] = $data['birthday']; $user_msg['height'] = $data['height']; $user_msg['weight'] = $data['weight']; diff --git a/application/ZengJieCode/controller/admin/Printaction.php b/application/ZengJieCode/controller/admin/Printaction.php index 124218e..8aba997 100644 --- a/application/ZengJieCode/controller/admin/Printaction.php +++ b/application/ZengJieCode/controller/admin/Printaction.php @@ -46,6 +46,7 @@ class Printaction extends Base a.mac_code, a.sn_code, b.box_code, + b.is_del, FORMAT(b.box_num, '000') AS box_num FROM sn_code_all AS a @@ -62,10 +63,10 @@ class Printaction extends Base return $result; }else{ $result2 = [ - ['Mac码','Sn码','箱号'] + ['Mac码','Sn码','箱号','是否注销'] ]; for ($i=0; $i < count($result); $i++) { - $result2[] = [$result[$i]['mac_code'],$result[$i]['sn_code'],$result[$i]['box_code'].'-'.$result[$i]['box_num']]; + $result2[] = [$result[$i]['mac_code'],$result[$i]['sn_code'],$result[$i]['box_code'].'-'.$result[$i]['box_num'],$result[$i]['is_del']==0?'否':'是']; } $excel = new \app\download\controller\Excel(); $excel->export($result2, $pc['box_code']); diff --git a/application/ZengJieCode/controller/app/Savemsg.php b/application/ZengJieCode/controller/app/Savemsg.php index b7cea54..893ce40 100644 --- a/application/ZengJieCode/controller/app/Savemsg.php +++ b/application/ZengJieCode/controller/app/Savemsg.php @@ -96,7 +96,7 @@ class Savemsg extends Base{ public function save_box_msg($data = ['sn_code_all'=>'564654564654654,564654564654654','box_serial_number'=>'996589585']){ - // try { + try { // 你的业务逻辑 if(count(input('post.')) > 0){ $data = input('post.'); @@ -115,22 +115,22 @@ class Savemsg extends Base{ } $result = $this->save_box_msg_action($data); return $result; - // } catch (\Exception $e) { - // // 捕获异常 - // $logContent["flie"] = $e->getFile(); - // $logContent["line"] = $e->getLine(); - // $logContent['all_content'] = "异常信息:\n"; - // $logContent['all_content'] .= "消息: " . $e->getMessage() . "\n"; - // $logContent['all_content'] .= "代码: " . $e->getCode() . "\n"; - // $logContent['all_content'] .= "文件: " . $e->getFile() . "\n"; - // $logContent['all_content'] .= "函数名: " . __FUNCTION__ . "\n"; - // $logContent['all_content'] .= "行号: " . $e->getLine() . "\n"; - // $logContent['all_content'] .= "跟踪信息:\n" . $e->getTraceAsString() . "\n"; - // // dump($data); - // // die; - // $this->record_api_log($data, $logContent, null); - // return $this->msg(99999); - // } + } catch (\Exception $e) { + // 捕获异常 + $logContent["flie"] = $e->getFile(); + $logContent["line"] = $e->getLine(); + $logContent['all_content'] = "异常信息:\n"; + $logContent['all_content'] .= "消息: " . $e->getMessage() . "\n"; + $logContent['all_content'] .= "代码: " . $e->getCode() . "\n"; + $logContent['all_content'] .= "文件: " . $e->getFile() . "\n"; + $logContent['all_content'] .= "函数名: " . __FUNCTION__ . "\n"; + $logContent['all_content'] .= "行号: " . $e->getLine() . "\n"; + $logContent['all_content'] .= "跟踪信息:\n" . $e->getTraceAsString() . "\n"; + // dump($data); + // die; + $this->record_api_log($data, $logContent, null); + return $this->msg(99999); + } } @@ -173,9 +173,14 @@ class Savemsg extends Base{ } } - + public function logout_outbox_code(){ + return $this->fetch(); + } + + + ########################################################################action######################################################################## ########################################################################action######################################################################## @@ -212,9 +217,20 @@ class Savemsg extends Base{ public function save_sn_msg_action($data){ $data = $this->chuli_str_kongbai($data); $zengjie = Db::connect('zengjie_db'); - $sn_code = $zengjie->table('sn_code_all')->where(['sn_code'=>$data['sn_code']])->count(); - if($sn_code > 0){ - return $this->msg(10002,'该码已录入'); + $sn_code = $zengjie->table('sn_code_all')->where(['sn_code'=>$data['sn_code']])->find(); + + if($sn_code){ + $box_state = $zengjie->table('box_code_all')->where(['id'=>$sn_code['batch_id']])->field('id,is_del')->find(); + if($box_state['is_del'] == 0){ + return $this->msg(10002,'该码已录入'); + }else{ + $sn_del_state = $zengjie->table('sn_code_all')->where(['id'=>$sn_code['id']])->delete(); + if ($sn_del_state) { + // return $this->msg(10000, '删除成功'); // 假设10000是成功代码 + } else { + return $this->msg(10002, '数据错误请重新尝试'); + } + } } $result = $zengjie->table('sn_code_all')->insert([ @@ -354,6 +370,24 @@ class Savemsg extends Base{ return $data; } + public function logout_outbox_code_action(){ + $data = input(); + // 处理前导零 + $boxNumber = ltrim($data['boxNumber'], '0'); + $boxNumber = $boxNumber === '' ? '0' : $boxNumber; + $zengjie = Db::connect('zengjie_db'); + $box_result = $zengjie->table('box_code_all')->where(['box_code'=>$data['boxCode'],'box_num'=>$boxNumber])->count(); + if($box_result <= 0){ + return $this->msg(10002,'未找到对应外箱编码'); + } + $result = $zengjie->table('box_code_all')->where(['box_code'=>$data['boxCode'],'box_num'=>$boxNumber])->update(['is_del'=>1]); + if($result){ + return $this->msg([]); + }else{ + return $this->msg(10002,'注销失败'); + } + } + ######################################################测试######################################################### ######################################################测试######################################################### ######################################################测试######################################################### diff --git a/application/ZengJieCode/view/admin/printaction/print_device_data_index.html b/application/ZengJieCode/view/admin/printaction/print_device_data_index.html index 1d10a3c..a30cfc1 100644 --- a/application/ZengJieCode/view/admin/printaction/print_device_data_index.html +++ b/application/ZengJieCode/view/admin/printaction/print_device_data_index.html @@ -32,12 +32,20 @@