diff --git a/application/KitchenScale/controller/app/Base.php b/application/KitchenScale/controller/app/Base.php index e07320e..664871e 100644 --- a/application/KitchenScale/controller/app/Base.php +++ b/application/KitchenScale/controller/app/Base.php @@ -208,6 +208,21 @@ class Base extends Controller{ } } + // 计算年龄 + public function calculate_age($data = '1991-04-20'){ + $today = time(); // 获取当前时间的 Unix 时间戳 + $birthDate = strtotime($data); // 将出生日期字符串转换为 Unix 时间戳 + if ($birthDate !== false) { + $age = date('Y', $today) - date('Y', $birthDate); + // 如果当前年份的月份和日期小于出生年份的月份和日期,那么年龄减一 + if (date('m-d', $today) < date('m-d', $birthDate)) { + $age--; + } + return $age; + } else { + return false; + } + } ####################################################图片选择上传start############################################################## public function pic_chose_list($page = 1) { $data = input(); diff --git a/application/KitchenScale/controller/app/Countfood.php b/application/KitchenScale/controller/app/Countfood.php index 0eb2d78..365d58a 100644 --- a/application/KitchenScale/controller/app/Countfood.php +++ b/application/KitchenScale/controller/app/Countfood.php @@ -17,7 +17,7 @@ class Login extends Base{ 'followlist'=>'app_user_follow_list',//关注列表 'collect_list'=>'app_user_collect_list',//收藏列表 'foodlist3'=>'app_food_type_three',//食材列表3 - 'user_kcal_log'=>'app_user_kcal_log',//食材列表3 + 'eat_log'=>'',//食材列表3 ]; @@ -29,8 +29,8 @@ class Login extends Base{ ################################################################接口################################################################ ################################################################接口################################################################ - // 保存每日餐食食物信息 - public function save_food_list($data=['token'=>'caadd1be045a65f30b92aa805f1de54a','food_list'=>[['name'=>'鸡肉','weight'=>456.37,'kcal'=>761.52]]]){ + // 添加每日摄入记录 + public function add_intake_food($data=['token'=>'caadd1be045a65f30b92aa805f1de54a','aud_id'=>1,'meals_type'=>'早餐','food_list'=>[['food_id'=>1,'weight'=>'500'],['food_id'=>1,'weight'=>'500']]]){ // 尝试捕获异常 // try { if(count(input('post.')) > 0){ @@ -39,15 +39,19 @@ class Login extends Base{ if(!array_key_exists('token', $data)){ return $this->msg(10001,'token is miss'); } + if(!array_key_exists('aud_id', $data)){ + return $this->msg(10001,'aud_id is miss'); + } if(!array_key_exists('food_list', $data)){ return $this->msg(10001,'food_list is miss'); } if(!$this->verify_data_is_ok($data['token'],'str')){ return $this->msg(10005,'token type is error'); } - - - $return_data = $this->save_food_list_action($data); + if(!$this->verify_data_is_ok($data['aud_id'],'intnum')){ + return $this->msg(10005,'aud_id type is error'); + } + $return_data = $this->add_intake_food_action($data); return $return_data; // } catch (\Exception $e) { // // 捕获异常 @@ -64,39 +68,378 @@ class Login extends Base{ // return json(['status' => 'error', 'message' => '系统错误']); // } } - #######################################################################action####################################################################### - #######################################################################action####################################################################### - #######################################################################action####################################################################### - - public function save_food_list_action($data){ - $cfc = Db::connect('cfc_db'); - foreach ($data['food_list'] as $key => $value) { - if(!array_key_exists('name', $value) || !array_key_exists('weight', $value) || !array_key_exists('kcal', $value)){ - return $this->msg(10001,'food_list content lost'); + // 获取记食器板块内容 + public function get_countfoot_content($data=['token'=>'caadd1be045a65f30b92aa805f1de54a','aud_id'=>1,'time'=>'2025-03-17']){ + // 尝试捕获异常 + // try { + if(count(input('post.')) > 0){ + $data = input('post.'); } - if(!$this->verify_data_is_ok($value['name'],'str')){ - return $this->msg(10005,'name type is error'); + if(!array_key_exists('token', $data)){ + return $this->msg(10001,'token is miss'); + } + if(!array_key_exists('aud_id', $data)){ + return $this->msg(10001,'aud_id is miss'); + } + if(!array_key_exists('time', $data)){ + return $this->msg(10001,'time is miss'); + } + if(!$this->verify_data_is_ok($data['token'],'str')){ + return $this->msg(10005,'token type is error'); + } + if(!$this->verify_data_is_ok($data['aud_id'],'intnum')){ + return $this->msg(10005,'aud_id type is error'); + } + if(!$this->verify_data_is_ok($data['time'],'datetime')){ + return $this->msg(10005,'time type is error'); + } + + $return_data = $this->get_countfoot_content_action($data); + return $return_data; + // } catch (\Exception $e) { + // // 捕获异常 + // $logContent["file"] = $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'] .= "行号: " . $e->getLine() . "\n"; + // $logContent['all_content'] .= "跟踪信息:\n" . $e->getTraceAsString() . "\n"; + // // 记录日志 + // // $this->record_api_log($data, $logContent, null); + // return json(['status' => 'error', 'message' => '系统错误']); + // } + } + // 获取记食器记录 + public function get_log_list($data=['token'=>'caadd1be045a65f30b92aa805f1de54a','aud_id'=>1,'page'=>1]){ + // 尝试捕获异常 + // try { + if(count(input('post.')) > 0){ + $data = input('post.'); + } + if(!array_key_exists('token', $data)){ + return $this->msg(10001,'token is miss'); + } + if(!array_key_exists('aud_id', $data)){ + return $this->msg(10001,'aud_id is miss'); + } + if(!array_key_exists('page', $data)){ + return $this->msg(10001,'page is miss'); + } + if(!$this->verify_data_is_ok($data['token'],'str')){ + return $this->msg(10005,'token type is error'); + } + if(!$this->verify_data_is_ok($data['aud_id'],'intnum')){ + return $this->msg(10005,'aud_id type is error'); + } + if(!$this->verify_data_is_ok($data['page'],'intnum')){ + return $this->msg(10005,'page type is error'); + } + + $return_data = $this->get_log_list_action($data); + return $return_data; + // } catch (\Exception $e) { + // // 捕获异常 + // $logContent["file"] = $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'] .= "行号: " . $e->getLine() . "\n"; + // $logContent['all_content'] .= "跟踪信息:\n" . $e->getTraceAsString() . "\n"; + // // 记录日志 + // // $this->record_api_log($data, $logContent, null); + // return json(['status' => 'error', 'message' => '系统错误']); + // } + } + + #######################################################################action####################################################################### + #######################################################################action####################################################################### + #######################################################################action####################################################################### + // 加 bcadd(,,20) + // 减 bcsub(,,20) + // 乘 bcmul(,,20) + // 除 bcdiv(,,20) + + public function add_intake_food_action($data){ + $cfc = Db::connect('cfc_db'); + // 统计食物的id + $food_id_arr = []; + foreach ($data['food_list'] as $key => $value) { + if(!array_key_exists('food_id', $value)){ + return $this->msg(10001,'food_id is miss'); + } + if(!array_key_exists('weight', $value)){ + return $this->msg(10001,'weight is miss'); + } + if(!$this->verify_data_is_ok($value['food_id'],'intnum')){ + return $this->msg(10005,'food_id type is error'); } if(!$this->verify_data_is_ok($value['weight'],'num')){ return $this->msg(10005,'weight type is error'); } - if(!$this->verify_data_is_ok($value['kcal'],'num')){ - return $this->msg(10005,'kcal type is error'); + array_push($food_id_arr,$value['id']); + } + + $food_content = $cfc->table($this->kitchenscale_db_msg['foodlist3']) + ->where("id in (".implode(',',$food_id_arr).")") + ->field('id,name,kcal,carbohydrate,protein,fat') + ->select(); + // 整理食物信息 + $food_content_arr = []; + foreach ($food_content as $key => $value) { + $food_content_arr[$value['id']] = $value; + } + $create_time = date('Y-m-d H:i:s'); + foreach ($data['food_list'] as $key => $value) { + //获取每100g食物的比例 + $proportion_num = bcdiv($value['weight'],100,2); + if(array_key_exists($value['id'], $food_content_arr)){ + $data['food_list'][$key]['kcal_val'] = bcmul($food_content_arr[$value['id']]['kcal'],$proportion_num,2); + $data['food_list'][$key]['carbohydrate_val'] = bcmul($food_content_arr[$value['id']]['carbohydrate'],$proportion_num,2); + $data['food_list'][$key]['protein_val'] = bcmul($food_content_arr[$value['id']]['protein'],$proportion_num,2); + $data['food_list'][$key]['fat_val'] = bcmul($food_content_arr[$value['id']]['fat'],$proportion_num,2); + $data['food_list'][$key]['aud_id'] = $data['aud_id']; + $data['food_list'][$key]['meals_type'] = $data['meals_type']; + $data['food_list'][$key]['food_name'] = $data['meals_type']; + $data['food_list'][$key]['create_time'] = $create_time; + }else{ + unset($data['food_list'][$key]); } } - if(!array_key_exists('eat_time', $data)){ - $data['eat_time'] = date('Y-m-d H:i:s'); + // 数据库数据字段:id,aud_id,meals_type,food_id,food_name,weight,kcal_val,carbohydrate_val,protein_val,fat_val,create_time + // 启动事务 + Db::startTrans(); + try{ + $result = $cfc->table($this->kitchenscale_db_msg['foodlist3'])->insertAll($data['food_list']); + if ($result !== count($data)) { + Db::rollback(); + return $this->msg(10002); + } else { + Db::commit(); + return $this->msg([]); + } + } catch (\Exception $e) { + // 回滚事务 + Db::rollback(); + return $this->msg(10002); + } + } + public function get_countfoot_content_action($data){ + $cfc = Db::connect('cfc_db'); + + $user_data = Db::table($this->reedaw_db_msg['juese']) + ->where(["id"=>$data['aud_id'],'token'=>$data['token']]) + ->field('weight,height,gender,birthday') + ->find(); + if(!$user_data){ + return $this->msg(10003); + } + + $user_data['age_num'] = $this->calculate_age($user_data['birthday']); + + $nutrition_data = $this->count_user_nutrition_all($user_data); + + // 查询用户今日摄入食物 + $food_content = $cfc->table($this->kitchenscale_db_msg['eat_log']) + // ->where(["aud_id"=>$data['aud_id'],'create_time'=>['=']]) + ->where("aud_id = ".$data['aud_id']." AND CAST(create_time AS DATE) = ".$data['time']."") + ->field('meals_type,food_name,weight,kcal_val,carbohydrate_val,protein_val,fat_val') + ->select(); + $date = date('Y-m-d H:i:s'); + $return_data = [ + 'suggestion'=>[ + 'kcal'=>$nutrition_data['tdee'], + 'carbohydrate'=>$nutrition_data['carbohydrate'].'克', + 'protein'=>$nutrition_data['protein'].'克', + 'fat'=>$nutrition_data['fat'].'克', + ], + 'today_intake'=>[ + 'kcal'=>0, + 'carbohydrate'=>0, + 'protein'=>0, + 'fat'=>0, + ], + 'remaining_kcal'=>$nutrition_data['tdee'],//剩下可摄入卡路里 + 'list'=>[ + [ + 'name'=>'早餐', + 'val'=>0, + 'unit'=>'kcal', + 'list'=>[], + ], + [ + 'name'=>'午餐', + 'val'=>0, + 'unit'=>'kcal', + 'list'=>[], + ], + [ + 'name'=>'晚餐', + 'val'=>0, + 'unit'=>'kcal', + 'list'=>[], + ], + [ + 'name'=>'加餐', + 'val'=>0, + 'unit'=>'kcal', + 'list'=>[], + ], + [ + 'name'=>'其他', + 'val'=>0, + 'unit'=>'kcal', + 'list'=>[], + ], + ], + 'date'=>date('Y-m-d'), + ]; + if(count($food_content) <= 0){ + return $this->msg($return_data); + } + foreach ($food_content as $key => $value) { + $return_data['today_intake']['kcal'] += $value['kcal_val']; + $return_data['today_intake']['carbohydrate'] += $value['carbohydrate_val']; + $return_data['today_intake']['protein'] += $value['protein_val']; + $return_data['today_intake']['fat'] += $value['fat_val']; + if($value['meals_type'] == '早餐'){ + $return_data['list'][0]['val'] += $value['kcal_val']; + array_push($return_data['list'][0]['list'],['name'=>$value['food_name'],'weight'=>$value['weight'].'克','val'=>$value['kcal_val'].'kcal']); + }else if($value['meals_type'] == '午餐'){ + $return_data['list'][1]['val'] += $value['kcal_val']; + array_push($return_data['list'][1]['list'],['name'=>$value['food_name'],'weight'=>$value['weight'].'克','val'=>$value['kcal_val'].'kcal']); + }else if($value['meals_type'] == '晚餐'){ + $return_data['list'][2]['val'] += $value['kcal_val']; + array_push($return_data['list'][2]['list'],['name'=>$value['food_name'],'weight'=>$value['weight'].'克','val'=>$value['kcal_val'].'kcal']); + }else if($value['meals_type'] == '加餐'){ + $return_data['list'][3]['val'] += $value['kcal_val']; + array_push($return_data['list'][3]['list'],['name'=>$value['food_name'],'weight'=>$value['weight'].'克','val'=>$value['kcal_val'].'kcal']); + }else{ + $return_data['list'][4]['val'] += $value['kcal_val']; + array_push($return_data['list'][4]['list'],['name'=>$value['food_name'],'weight'=>$value['weight'].'克','val'=>$value['kcal_val'].'kcal']); + } + } + $return_data['today_intake'] = $return_data['suggestion']['kcal']-$return_data['today_intake']['kcal']>=0?$return_data['suggestion']['kcal']-$return_data['today_intake']['kcal']:0; + return $this->msg($return_data); + } + + public function get_log_list_action($data){ + $cfc = Db::connect('cfc_db'); + $user_data = Db::table($this->reedaw_db_msg['juese']) + ->where(["id"=>$data['aud_id'],'token'=>$data['token']]) + ->field('weight,height,gender,birthday') + ->find(); + if(!$user_data){ + return $this->msg(10003); + } + // 计算年龄 + $user_data['age_num'] = $this->calculate_age($user_data['birthday']); + // 计算推荐营养 + $nutrition_data = $this->count_user_nutrition_all($user_data); + // 计算取值范围 + $time_arr = $this->calculateDateRange($data['page']); + + $food_content = $cfc->table($this->kitchenscale_db_msg['eat_log']) + ->where(['aud_id'=>$data['aud_id']]) + ->whereTime('create_time', 'between', [$time_arr['s_time'], $time_arr['e_time']]) + ->field('kcal_val,create_time') + ->order('create_time desc') + ->select(); + $user_log = []; + foreach ($food_content as $key => $value) { + if(array_key_exists($value['create_time'], $user_log)){ + $user_log[$value['create_time']] += $value['kcal_val']; + }else{ + $user_log[$value['create_time']] = $value['kcal_val']; + } + } + $return_data = []; + foreach ($variable as $key => $value) { + if(bcdiv($value,$nutrition_data['kcal'],2) < 0.9){ + $bz['text'] = '不达标'; + $bz['color'] = '#F1D452'; + }else if(bcdiv($value,$nutrition_data['kcal'],2) >= 0.9 && bcdiv($value,$nutrition_data['kcal'],2) < 1.1){ + $bz['text'] = '达标'; + $bz['color'] = '#66AE00'; + }else{ + $bz['text'] = '超标'; + $bz['color'] = '#D7001A'; + } + array_push($return_data,['time'=>$key,'val'=>$value,'unit'=>'kcal','describe'=>$bz['text'],'color'=>$bz['color']]); + } + return $this->msg($return_data); + } + + #######################################################################工具####################################################################### + #######################################################################工具####################################################################### + #######################################################################工具####################################################################### + + 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,20); + }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,20); }else{ - if(!$this->verify_data_is_ok($data['eat_time'],'datetime')){ - return $this->msg(10005,'eat_time type is error'); - } + return $this->msg(10003,'性别未知'); } - $result = $cfc->table($this->kitchenscale_db_msg['user_kcal_log']) - ->insert([ - 'food_name'=> - ]); + // 每日总能量消耗(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]; + } + public function calculateDateRange($n) { + // 获取当前日期和时间 + $today = new DateTime(); + + // 计算结束时间:往前推 (10 * (n - 1)) 天,时间设为 23:59:59 + $endInterval = new DateInterval('P' . (10 * ($n - 1)) . 'D'); + $endTime = clone $today; + $endTime->sub($endInterval)->setTime(23, 59, 59); + + // 计算开始时间:往前推 (10 * n) 天,时间设为 00:00:00 + $startInterval = new DateInterval('P' . (10 * $n) . 'D'); + $startTime = clone $today; + $startTime->sub($startInterval)->setTime(0, 0, 0); + + return [ + 's_time' => $startTime->format('Y-m-d H:i:s'), + 'e_time' => $endTime->format('Y-m-d H:i:s'), + ]; } } \ No newline at end of file