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

548 lines
23 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\KitchenScale3\controller\app;
use think\Controller;
use think\Db;
use think\Cache;
use think\Log;
use PHPMailer\PHPMailer\PHPMailer;
class Base extends Controller{
protected $base_use_db_name = [
'search_history'=>'app_user_search_history_multilingual',
'foodlist4'=>'app_z_national_standard_food_type_4_multilingual',
'user'=>'app_user_data_multilingual'
];
protected $token_time = 30;//30天的秒数
protected $file_size = 5*1024*1024;
protected $return_data_all = [
'10001'=>'关键参数缺失',
'10002'=>'操作失败',
'10003'=>'信息核实错误',
'10004'=>'未找到有效数据',
'10005'=>'参数格式错误',
'10006'=>'参数不能为空',
'10007'=>'参数错误',
'10008'=>'',
'10009'=>'',
'10010'=>'自定义信息',
'20001'=>'登录失效',
'99999'=>'网络异常,请稍后重试',
];
// 加 bcadd(,,20)
// 减 bcsub(,,20)
// 乘 bcmul(,,20)
// 除 bcdiv(,,20)
################################################################接口监控################################################################
################################################################接口监控################################################################
################################################################接口监控################################################################
// 接口记录
public function record_api_log($params, $error = null, $response = null){
// dump($params);
// dump($error);
// die;
$logContent = "接口请求参数:" . json_encode($params, JSON_UNESCAPED_UNICODE) . PHP_EOL;
if ($error) {
$logContent .= "错误信息:" . $error['all_content'] . PHP_EOL;
if(!cache($error['flie']."_".$error['line'])){
cache($error['flie']."_".$error['line'],"API错误",3600);
$this->send_email_api_error(["tsf3920322@126.com"],['title'=>'接口报错','from_user_name'=>'厨房秤(海外)(后台)','content'=>$logContent]);
}
}
if ($response) {
$logContent .= "返回信息:" . json_encode($response, JSON_UNESCAPED_UNICODE) . PHP_EOL;
}
// 使用ThinkPHP的日志记录方法
Log::record($logContent, 'api_log');
}
/* 接口说明(发邮件)
* $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 check_code($data = 18530934717 , $code = 123456){
// // 默认验证码正确
if(cache($data) == false){
return '验证码过期';
}else{
if($code != cache($data)){
return '验证码错误';
}
}
return true;
}
// 判断字符串是手机还是邮箱
public function is_tel_email($str) {
// 手机号码的正则表达式(中国大陆格式)(下面正则实际判断的是是否为11位数字)
$mobilePattern = '/^\d{11}$/';
// 电子邮件地址的正则表达式
$emailPattern = '/^[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/';
// 判断是否为手机号码
if (preg_match($mobilePattern, $str)) {
return 'tel';
}
// 判断是否为电子邮件地址
if (preg_match($emailPattern, $str)) {
return 'email';
}
// 如果都不是,返回其他
return false;
}
// 判断token是否过期
public function token_time_validate($token){
// 591b70e0d80b5fa6d77e6e1384453ab9
if(is_string($token)){
$length = strlen($token);
if ($length < 10 ) {
Log::record('用户尝试更新token时间token' . $token.',但是更新token失败字符串长度小于10', 'token_log');
return false;
}
}else{
Log::record('用户尝试更新token时间token' . $token.',但是更新token失败不是字符串', 'token_log');
return false;
}
$cfc = Db::connect('cfc_db');
$user_login = $cfc->table($this->base_use_db_name['user'])->where(['token'=>$token])->field('id,login_time')->find();
if(!$user_login){
Log::record('用户尝试更新token时间token' . $token.',但是更新token失败未找到用户token', 'token_log');
return false;
}
// 创建 DateTime 对象来表示指定的日期和时间
$specifiedDateTime = new \DateTime($user_login['login_time']);
// 获取当前时间的 DateTime 对象
$currentDateTime = new \DateTime();
// 计算两个日期之间的差异(以秒为单位)
$interval = $currentDateTime->diff($specifiedDateTime);
// 将差异转换为天数(注意:这里的天数可能不是整数,因为差异可能包括小时、分钟等)
$daysDifference = $interval->days;
// 如果需要更精确的计算(包括小时、分钟等转换成的天数),可以使用以下方式:
// $totalSecondsDifference = $interval->format('%a') * 86400 + $interval->format('%h') * 3600 + $interval->format('%i') * 60 + $interval->format('%s');
// $daysDifference = floor($totalSecondsDifference / 86400); // 将总秒数转换为天数并取整
// 判断差异是否超过指定的天数
if ($daysDifference > $this->token_time) {
// echo "超过 {$specifiedDays} 天";
Log::record('用户尝试更新token时间token' . $token.',但是更新token失败原因没有找到该token,或该token已经超过30天', 'token_log');
return false;
} else {
// echo "未超过 {$specifiedDays} 天";
$user_login = $cfc->table($this->base_use_db_name['user'])->where(['token'=>$token])->update(['login_time'=>date('Y-m-d H:i:s')]);
if($user_login){
Log::record('用户尝试更新token时间token' . $token.',记录成功,最新的时间为'.date('Y-m-d H:i:s'), 'token_log');
return true;
}else{
Log::record('用户尝试更新token时间token' . $token.',但是更新token失败数据库更新时间未成功', 'token_log');
return true;
}
}
}
// 验证数据类型
public function verify_data_is_ok($data = 2,$type){
if($type == 'str'){
if (is_string($data)) {
return true;
} else {
$this->record_api_log($data, null, ['code'=>10005,'msg'=>'校验参数不为字符串',[]]);
return false;
}
}else if($type == 'num'){
if (is_numeric($data)) {
return true;
} else {
$this->record_api_log($data, null, ['code'=>10005,'msg'=>'校验参数不为数字',[]]);
return false;
}
}else if($type == 'intnum'){
$pattern = '/^\d+$/';
// dump($data);
if (preg_match($pattern, $data)) {
return true; // 匹配成功,返回 true
} else {
$this->record_api_log($data, null, ['code'=>10005,'msg'=>'校验参数不为整数数字',[]]);
return false; // 匹配失败,返回 false
}
}else if($type == 'datetime'){
$formats = ['Y-m-d','Y-m-d H:i:s'];
foreach ($formats as $format) {
$dateTime = \DateTime::createFromFormat($format, $data);
// 检查时间字符串是否成功解析,并且解析后的日期时间与原始字符串表示的时间一致
if ($dateTime && $dateTime->format($format) === $data) {
return true;
}
}
// 如果所有格式都解析失败,则返回 false
$this->record_api_log($data, null, ['code'=>10005,'msg'=>'校验参数不为日期格式',[]]);
return false;
}else if($type == 'other'){
}
}
// 计算年龄
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;
}
}
// 计算常规卡路里
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
if(array_key_exists('activity_level',$data)){
if($data['activity_level'] != null){
$tdee = bcmul($bmr,$data['activity_level'],2);
}else{
$tdee = bcmul($bmr,1.55,2);
}
}else{
$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_p = 0.5;
$carbohydrate = bcdiv(bcmul($tdee,0.5,20),4,2);
if($data['age_num'] < 65){
$protein_p = 0.2;
$fat_p = 0.3;
$protein = bcdiv(bcmul($tdee,0.2,20),4,2);
$fat = bcdiv(bcmul($tdee,0.3,20),9,2);
}else{
$protein_p = 0.25;
$fat_p = 0.25;
$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,'carbohydrate_p'=>$carbohydrate_p,'protein_p'=>$protein_p,'fat_p'=>$fat_p];
}
/**
* 将重量转换为克(g)
* @param string $weight 重量值
* @param string $unit 单位 (g, oz, lb, lb:oz)
* @return float 转换后的克重
*/
function convertWeightToGrams($weight, $unit) {
// 定义精确的转换常量
$G_PER_OZ = '28.349523125';
$G_PER_LB = '453.59237';
$unit = strtolower($unit);
$result = 0;
switch ($unit) {
case 'g':
case '克':
// 已经是克,直接返回
$result = $weight;
break;
case 'oz':
case '盎司':
// 盎司转克
$result = bcmul($weight,$G_PER_OZ,2);
break;
case 'lb':
case '磅':
// 磅转克
$result = bcmul($weight,$G_PER_LB,2);
break;
case 'lb:oz':
case '磅:盎司':
// 磅:盎司复合单位处理
if (strpos($weight, ':') !== false) {
$temporary_data = explode(':', $weight);
$result = bcadd(bcmul($temporary_data[0],$G_PER_LB,20),bcmul($temporary_data[1],$G_PER_OZ,20),2);
} else {
// 如果格式不正确可以抛出异常或返回0
$result = '0';
}
break;
default:
$result = '0';
}
// 保留两位小数并返回
return $result;
}
// 计算营养物质
public function calculate_nutrients($data){
// dump($data);
$food_id_arr = [];
for ($i=0; $i < count($data); $i++) {
$food_id_arr[] = $data[$i]['food_id'];
}
$cfc = Db::connect('cfc_db');
$nutrients_list = $cfc->table($this->base_use_db_name['foodlist4'])
->where("father_id in ('".implode("','",$food_id_arr)."')")
// ->field()
->select();
$nutrients_arr = ['VitaminA','VitaminB1','VitaminB2','VitaminB6','VitaminB12','VitaminD','VitaminK','Niacin','VitaminC','VitaminE','FolicAcid','Biotin','PantothenicAcid','TotalCholine','Ca','Phosphorus','Kalium','Mg','Na','Fe','Zn','Se','Cu','Mn','Iodine'];
// dump($nutrients_list);
// 加 bcadd(,,20)
// 减 bcsub(,,20)
// 乘 bcmul(,,20)
// 除 bcdiv(,,20)
for ($i=0; $i < count($data); $i++) {
$zong_all = bcadd($data[$i]['protein_val'],bcadd($data[$i]['fat_val'],$data[$i]['carbohydrate_val'],20),20);
$data[$i]['nutrients_four'][] = [
'name' => '卡路里',
'unit' => 'kcal',
'color' => '',
'value' => $data[$i]['kcal_val'],
'proportion' => 0,
];
$data[$i]['nutrients_four'][] = [
'name' => '蛋白质',
'unit' => 'g',
'color' => '#5180D8',
'value' => $data[$i]['protein_val'],
'proportion' => $zong_all == 0?0:bcmul(bcdiv($data[$i]['protein_val'],$zong_all,2),100,0),
];
$data[$i]['nutrients_four'][] = [
'name' => '脂肪',
'unit' => 'g',
'color' => '#ED7886',
'value' => $data[$i]['fat_val'],
'proportion' => $zong_all == 0?0:bcmul(bcdiv($data[$i]['fat_val'],$zong_all,2),100,0),
];
$data[$i]['nutrients_four'][] = [
'name' => '碳水化合物',
'unit' => 'g',
'color' => '#FFB169',
'value' => $data[$i]['carbohydrate_val'],
'proportion' => $zong_all == 0?0:bcmul(bcdiv($data[$i]['carbohydrate_val'],$zong_all,2),100,0),
];
$data[$i]['nutrients_list'][] = [
'name' => 'Calorie',
'name_ch' => '卡路里',
'unit' => 'kcal',
'value' => $data[$i]['kcal_val'],
'type' => 1,
'type_name' => '能量及宏量营养素',
'color' => '#C4FFE0',
];
$data[$i]['nutrients_list'][] = [
'name' => 'Protein',
'name_ch' => '蛋白质',
'unit' => 'g',
'value' => $data[$i]['protein_val'],
'type' => 1,
'type_name' => '能量及宏量营养素',
'color' => '#C4FFE0',
];
$data[$i]['nutrients_list'][] = [
'name' => 'Fat',
'name_ch' => '脂肪',
'unit' => 'g',
'value' => $data[$i]['fat_val'],
'type' => 1,
'type_name' => '能量及宏量营养素',
'color' => '#C4FFE0',
];
$data[$i]['nutrients_list'][] = [
'name' => 'Carbohydrate',
'name_ch' => '碳水化合物',
'unit' => 'g',
'value' => $data[$i]['carbohydrate_val'],
'type' => 1,
'type_name' => '能量及宏量营养素',
'color' => '#C4FFE0',
];
foreach ($nutrients_list as $key => $value) {
if($value['father_id'] == $data[$i]['food_id']){
if(in_array($value['name'],$nutrients_arr)){
$data[$i]['nutrients_list'][] = [
'name' => $value['name'],
'name_ch' => $value['name_ch'],
'unit' => $value['unit'],
'value' => bcmul($value['value'],bcdiv($data[$i]['weight'],100,20),2),
'type' => $value['type'],
'type_name' => $value['type'] == 1?'能量及宏量营养素':($value['type'] == 2?'维生素':($value['type'] == 3?'矿物质':'')),
'color' => $value['type'] == 1?'#C4FFE0':($value['type'] == 2?'#FFEFB7':($value['type'] == 3?'#7DA8E0':'')),
];
}
}
}
}
return $data;
}
public function add_search_history_action($data){
// 添加一条搜索记录start
$cfc = Db::connect('cfc_db');
$insert_search_log = $cfc->table($this->base_use_db_name['search_history'])->where(['user_id'=>$data['id'],'keyword'=>$data['search_data'],'type'=>$data['type']])->field('id,search_count')->find();
if($insert_search_log){
$cfc->table($this->base_use_db_name['search_history'])->where(['id'=>$insert_search_log['id']])->update([
'search_count'=>$insert_search_log['search_count']+1,
'last_searched_at'=>date('Y-m-d H:i:s'),
]);
}else{
$cfc->table($this->base_use_db_name['search_history'])->insert([
'user_id'=>$data['id'],
'keyword'=>$data['search_data'],
'type'=>$data['type'],
]);
}
// 添加一条搜索记录end
}
####################################################图片选择上传start##############################################################
####################################################图片选择上传start##############################################################
####################################################图片选择上传start##############################################################
####################################################图片选择上传end##############################################################
####################################################图片选择上传end##############################################################
####################################################图片选择上传end##############################################################
########################################################其他工具########################################################
########################################################其他工具########################################################
########################################################其他工具########################################################
public function msg($data,$str='',$result = []){
if(is_array($data)){
if($str != ''){
return json(['code'=>0,'msg'=>$str,'data'=>$data]);
}else{
return json(['code'=>0,'msg'=>'操作成功','data'=>$data]);
}
}else{
if($str != ''){
return json(['code'=>$data,'msg'=>$str,'data'=>$result]);
}
return json(['code'=>$data,'msg'=>$this->return_data_all[$data],'data'=>$result]);
}
}
public function generateRandomString($length = 10) {
$characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}
public function ceshi(){
echo 'hello';
}
}