Compare commits

...

6 Commits

Author SHA1 Message Date
tiansf 8d3b39a59c 部分线上测试 2025-01-22 12:31:08 +08:00
tiansf 9fce437479 测试两个数据库内用户数据连通性 2025-01-04 19:08:03 +08:00
tiansf 8f7660e7d8 测试单文件 2024-12-31 18:43:03 +08:00
tiansf 22ac8a8ee6 241231 2024-12-31 18:42:33 +08:00
tiansf a4ef494a84 测试提交2 2024-12-26 19:15:38 +08:00
tiansf f12c82f274 提交测试 2024-12-26 19:14:44 +08:00
103 changed files with 8065 additions and 1798 deletions

1
.gitignore vendored
View File

@ -6,3 +6,4 @@ composer.lock
/runtime
runtime
/.htaccess
/public/nginx.htaccess

View File

@ -0,0 +1,170 @@
<?php
namespace app\KitchenScale\controller\admin;
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 = [
'1'=>'test_app_data_log',
];
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){
$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 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+$/';
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 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 ceshi(){
echo 'hello';
}
}

View File

@ -0,0 +1,119 @@
<?php
namespace app\KitchenScale\controller\admin;
use think\Db;
class Login extends Base{
protected $login_hours_out = 24;
// 加 bcadd(,,20)
// 减 bcsub(,,20)
// 乘 bcmul(,,20)
// 除 bcdiv(,,20)
################################################################接口################################################################
################################################################接口################################################################
################################################################接口################################################################
// 登录请求api
public function login($data = ['account'=>123,'password'=>456]){
// try {
// 你的业务逻辑
if(count(input('post.')) > 0){
$data = input('post.');
}
if(!array_key_exists('account', $data) || !array_key_exists('password', $data)){
return $this->msg(10001);
}
$return_data = $this->login_action($data);
// 成功
$this->record_api_log($data, null, $return_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'] .= "代码: " . $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);
// }
}
// 检测登录信息是否超时
public function check_login($data = ['token'=>'123']){
// try {
// 你的业务逻辑
if(count(input('post.')) > 0){
$data = input('post.');
}
if(!array_key_exists('token', $data)){
return $this->msg(10001);
}
$return_data = $this->check_login_action($data);
// 成功
$this->record_api_log($data, null, $return_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'] .= "代码: " . $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);
// }
}
#######################################################################action#######################################################################
public function login_action($data){
// dump($data);
$user = Db::table('admin_user_account_number')->where(["account_num"=>$data['account'],'password'=>$data['password']])->find();
// dump($user);
// die;
if($user){
return $this->msg(['token'=>$user['token']]);
}else{
return $this->msg(10004);
}
}
public function check_login_action(){
$user = Db::table('admin_user_account_number')->where(["token"=>$data['token']])->field('create_time')->find();
if (!$user) {
return $this->msg(10001); // 如果用户不存在,直接返回 false
}
// 假设 $user['create_time'] 是一个日期时间字符串
$createTime = new DateTime($user['create_time']);
$currentTime = new DateTime();
// 计算时间差
$interval = $currentTime->diff($createTime);
// 判断时间差是否超过指定小时数
$totalHours = $interval->days * 24 + $interval->h;
if ($totalHours > $this->login_hours_out) {
return $this->msg(10001);
} else {
return $this->msg([]);
}
}
}

View File

@ -0,0 +1,294 @@
<?php
namespace app\KitchenScale\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 = [
'1'=>'test_app_data_log',
];
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){
$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 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'){
}
}
####################################################图片选择上传start##############################################################
public function pic_chose_list($page = 1) {
$data = input();
if(!array_key_exists('token',$data)){
return $this->msg(10001,'token is miss');
}
if(array_key_exists('page',$data)){
$page = $data['page'];
}
$parameter_data = [
'user_token'=>$data['token'],
'is_del'=>0
];
$cfc = Db::connect('cfc_db');
$num = $cfc->table('app_user_upload_img')->where($parameter_data)->count();
$result = $cfc->table('app_user_upload_img')->where($parameter_data)->order('id desc')->page($page,20)->field('id,pic_name,pic_url')->select();
$return_result['total_num'] = $num;
$return_result['page_now'] = $page;
$return_result['result'] = $result;
return $this->msg($return_result);
}
public function pic_upload_action(){
$insert_data = [];
$temporary_data = [];
$miss_data = 0;
$cfc = Db::connect('cfc_db');
$files = request()->file('images');
$token = request()->param('token');
if(!$token){
return $this->msg(10001,'token is miss');
}
if($files){
foreach($files as $file){
$name = $file->getInfo()['name'];
// 使用 pathinfo() 函数获取文件名的扩展名
$pathinfo = pathinfo($name);
$extension = strtolower($pathinfo['extension']); // 转换为小写以进行不区分大小写的比较
$file_name = $pathinfo['filename'];
// 判断扩展名是否不是 .png 或 .gif
if ($extension !== 'png' && $extension !== 'gif') {
// 修改文件名,将扩展名改为 .jpg
$new_filename = time().$this->generateRandomString(). '.jpg';
} else {
$new_filename = time().$this->generateRandomString(). '.' . $extension;
}
$info = $file->validate(['size'=>$this->file_size,'ext'=>'jpg,png,gif'])->move(ROOT_PATH . 'public' . DS . 'kitchenscale_all' . DS . 'user_upload',$new_filename);
if($info){
$temporary_data = [
'user_token'=>$token,
'pic_name'=>$new_filename,
'pic_url'=>"https://tc.pcxbc.com/kitchenscale_all/user_upload/".$new_filename,
// 'pic_url'=>"http://wm.tcxbc.com/kitchenscale_all/user_upload/".$new_filename,
'create_time'=>date('Y-m-d H:i:s'),
];
$pic_id = $cfc->table('app_user_upload_img')->insertGetId($temporary_data);
if($pic_id){
$temporary_data['id'] = $pic_id;
unset($temporary_data['create_time']);
unset($temporary_data['user_token']);
array_push($insert_data,$temporary_data);
}else{
$miss_data = $miss_data+1;
}
}else{
$miss_data = $miss_data+1;
}
}
return $this->msg(['error_data'=>$miss_data,'insert_data'=>$insert_data]);
}else{
return $this->msg(10001,'未选择图片');
}
// dump($file);
die;
if($file){
$name = $file->getInfo()['name'];
// 使用 pathinfo() 函数获取文件名的扩展名
$pathinfo = pathinfo($name);
$extension = strtolower($pathinfo['extension']); // 转换为小写以进行不区分大小写的比较
$file_name = $pathinfo['filename'];
// 判断扩展名是否不是 .png 或 .gif
if ($extension !== 'png' && $extension !== 'gif') {
// 修改文件名,将扩展名改为 .jpg
$new_filename = date('YmdHis').$file_name . '.jpg';
} else {
$new_filename = date('YmdHis').$name;
}
$info = $file->validate(['size'=>$this->file_size,'ext'=>'jpg,png,gif'])->move(ROOT_PATH . 'public' . DS . 'upload_pic',$new_filename);
if($info){
$insert_data = [
'url_data'=>"https://tc.pcxbc.com/upload_pic/".$new_filename,
'name'=>$new_filename,
'create_time'=>date('Y-m-d H:i:s'),
];
$pic_result = Db::table('admin_pic_manage')->insertGetId($insert_data);
if($pic_result){
return $this->msg(['url'=>$insert_data['url_data'],'id'=>$pic_result]);
}else{
return $this->msg(10002,'图片数据保存失败');
}
}else{
return $this->msg(10002,'图片上传失败');
}
}
}
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';
}
}

View File

@ -0,0 +1,787 @@
<?php
namespace app\KitchenScale\controller\app;
use think\Db;
class Cookbook extends Base{
protected $code_time = 50;
// protected $token_time = 2592000;//30天的秒数
protected $default_head_pic = 'http://tc.pcxbc.com/tsf/head_pic.png';
protected $reedaw_db_msg = [
'zhanghao'=>'app_account_number',//账号表
'juese'=>'app_user_data',//角色表
];
protected $kitchenscale_db_msg = [
'cookbook'=>'app_user_cookbook',//菜谱表
'uploadimg'=>'app_user_upload_img',//素材表
'followlist'=>'app_user_follow_list',//关注列表
'collectlist'=>'app_user_collect_list',//收藏列表
];
// 加 bcadd(,,20)
// 减 bcsub(,,20)
// 乘 bcmul(,,20)
// 除 bcdiv(,,20)
################################################################接口################################################################
################################################################接口################################################################
################################################################接口################################################################
// 添加菜谱
public function add_cookbook(){
// 尝试捕获异常
// 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('cover', $data)){
return $this->msg(10001,'cover is miss');
}
if(!array_key_exists('description', $data)){
return $this->msg(10001,'description is miss');
}
if(!array_key_exists('cook_label', $data)){
return $this->msg(10001,'cook_label is miss');
}
if(!array_key_exists('food_list', $data)){
$data['food_list'] = [];
}
if(!array_key_exists('step_list', $data)){
$data['step_list'] = [];
}
if(!$this->verify_data_is_ok($data['token'],'str')){
return $this->msg(10005,'token type is error');
}
if(!$this->verify_data_is_ok($data['cover'],'intnum')){
return $this->msg(10005,'cover type is error');
}
if(!$this->verify_data_is_ok($data['description'],'str')){
return $this->msg(10005,'description type is error');
}
if (!is_array($data['food_list'])) {
return $this->msg(10005,'food_list type is error');
}
if (!is_array($data['step_list'])) {
return $this->msg(10005,'step_list type is error');
}
$return_data = $this->add_cookbook_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 find_by_cook_label($data=['token'=>'caadd1be045a65f3','cook_label'=>'早餐','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('cook_label', $data)){
return $this->msg(10001,'cook_label 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['cook_label'],'str')){
return $this->msg(10005,'cook_label type is error');
}
if(!$this->verify_data_is_ok($data['page'],'intnum')){
return $this->msg(10005,'page type is error');
}
$return_data = $this->find_by_cook_label_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 find_by_food($data=['token'=>'caadd1be045a65f3','food_name'=>'猪肉','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('food_name', $data)){
return $this->msg(10001,'food_name 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['food_name'],'str')){
return $this->msg(10005,'food_name type is error');
}
if(!$this->verify_data_is_ok($data['page'],'intnum')){
return $this->msg(10005,'page type is error');
}
$return_data = $this->find_by_food_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 cookbook_details($data=['token'=>'caadd1be045a65f30b92aa805f1de54a','cookbook_id'=>'12']){
// 尝试捕获异常
// 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('cookbook_id', $data)){
return $this->msg(10001,'cookbook_id 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['cookbook_id'],'intnum')){
return $this->msg(10005,'cookbook_id type is error');
}
$return_data = $this->cookbook_details_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 cookbook_follow($data=['token'=>'caadd1be045a65f3','cookbook_id'=>'12']){
// 尝试捕获异常
// 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('cookbook_id', $data)){
return $this->msg(10001,'cookbook_id 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['cookbook_id'],'intnum')){
return $this->msg(10005,'cookbook_id type is error');
}
$return_data = $this->cookbook_follow_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 cookbook_like($data=['token'=>'caadd1be045a65f3','cookbook_id'=>'12']){
// 尝试捕获异常
// 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('cookbook_id', $data)){
return $this->msg(10001,'cookbook_id 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['cookbook_id'],'intnum')){
return $this->msg(10005,'cookbook_id type is error');
}
$return_data = $this->cookbook_like_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 cookbook_count_weight($data=['token'=>'caadd1be045a65f30b92aa805f1de54a','cookbook_id'=>'12','food_weight'=>[]]){
// 尝试捕获异常
// 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('cookbook_id', $data)){
return $this->msg(10001,'cookbook_id is miss');
}
if(!array_key_exists('food_weight', $data)){
return $this->msg(10001,'food_weight 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['cookbook_id'],'intnum')){
return $this->msg(10005,'cook_label type is error');
}
$return_data = $this->cookbook_count_weight_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#######################################################################
public function add_cookbook_action($data){
if(count($data['food_list']) < 1){
return $this->msg(10005,'至少添加一个食物');
}
if(count($data['step_list']) < 1){
return $this->msg(10005,'至少添加一个步骤');
}
$food_type = [];
// 检验一下food_list是否合规食材列表
foreach ($data['food_list'] as $key => $value) {
if (!array_key_exists('name', $value) || !array_key_exists('weight', $value)) {
return $this->msg(10005,'食材缺少名称或者重量');
}
if(!$this->verify_data_is_ok($value['name'],'str')){
return $this->msg(10005,'食材名称格式错误,需字符串');
}
if(!$this->verify_data_is_ok($value['weight'],'intnum')){
return $this->msg(10005,'食材重量格式错误,需整数数字');
}
array_push($food_type, $value['name']);
}
// 检验一下step_list是否合规步骤列表
foreach ($data['step_list'] as $key => $value) {
// if (!array_key_exists('description', $value) || !array_key_exists('foot_list', $value) || !array_key_exists('pic_list', $value)) {
if (!array_key_exists('description', $value) || !array_key_exists('pic_list', $value)) {
return $this->msg(10005,'步骤缺少描述或者图片');
}
if(!$this->verify_data_is_ok($value['description'],'str')){
return $this->msg(10005,'步骤描述格式错误,需要正常字符');
}
foreach ($value['pic_list'] as $k => $v) {
if(!$this->verify_data_is_ok($v,'intnum')){
return $this->msg(10005,'步骤中图片ID错误,需整数数字');
}
}
// foreach ($value['foot_list'] as $k => $v) {
// if (!array_key_exists('name', $v) || !array_key_exists('weight', $v)) {
// return $this->msg(10005,'步骤食材缺少名称或者重量');
// }
// if(!$this->verify_data_is_ok($v['name'],'str')){
// return $this->msg(10005,'步骤食材名称格式错误,需字符串');
// }
// if(!$this->verify_data_is_ok($v['weight'],'intnum')){
// return $this->msg(10005,'步骤食材重量格式错误,需整数数字');
// }
// }
}
$cfc = Db::connect('cfc_db');
// 获取账号下信息以及用户信息
$user_data = Db::table($this->reedaw_db_msg['zhanghao'])->where(['token'=>$data['token']])->field('id,token,nickname,head_pic')->find();
// 处理食材卡路里start
foreach ($data['food_list'] as $key => $value) {
$data['food_list'][$key]['kcal'] = '0kcal';
}
// foreach ($data['step_list'] as $key => $value) {
// foreach ($value['foot_list'] as $k => $v) {
// $data['step_list'][$key]['foot_list'][$k]['kcal'] = '0kcal';
// }
// }
// 处理食材卡路里end
$insert_data = [
'title'=>$data['title'],
'cover'=>$data['cover'],
'create_user_token'=>$user_data['token'],
'create_user_head_pic'=>$user_data['head_pic'],
'create_user_nickname'=>$user_data['nickname'],
'describe_data'=>$data['description'],
'food_data'=>json_encode($data['food_list']),
'step_data'=>json_encode($data['step_list']),
'food_type'=>implode(',', $food_type),
'cook_label'=>$data['cook_label'],
'create_time'=>date('Y-m-d H:i:s')
];
$cook_book_result = $cfc->table($this->kitchenscale_db_msg['cookbook'])->insert($insert_data);
if($cook_book_result){
return $this->msg([]);
}else{
return $this->msg(10002);
}
}
public function find_by_cook_label_action($data){
$page_now = $data['page'];
$page_total = $data['page'];
$page_num = 20;
$cook_label = $data['cook_label'];
$cfc = Db::connect('cfc_db');
$content_num = $cfc->table($this->kitchenscale_db_msg['cookbook'])
->where(['cook_label'=>$cook_label])
->count();
$page_total = ceil($content_num/$page_num);
$content_list = $cfc->table($this->kitchenscale_db_msg['cookbook'])
->alias('cookbook')
->join($this->kitchenscale_db_msg['uploadimg'].' uploadimg','cookbook.cover = uploadimg.id','LEFT')
->where(['cookbook.cook_label'=>$cook_label])
->field('cookbook.id,cookbook.title,uploadimg.pic_url as cover,cookbook.create_user_head_pic,cookbook.create_user_nickname,cookbook.like_it as like_num')
->page("$page_now,$page_num")
->select();
// 处理本人是否关注 start
$like_it_arr = [];
foreach ($content_list as $key => $value) {
array_push($like_it_arr, $value['id']);
}
$like_it_data = $cfc->table($this->kitchenscale_db_msg['collectlist'])
->where("token = '".$data['token']."' AND cookbook_id in (".implode(',',$like_it_arr).") AND is_del = 0")
->select();
$like_it_arr2 = [];
foreach ($like_it_data as $key => $value) {
array_push($like_it_arr2, $value['cookbook_id']);
}
foreach ($content_list as $key => $value) {
if(in_array($value['id'],$like_it_arr2)){
$content_list[$key]['is_like'] = 1;
}else{
$content_list[$key]['is_like'] = 0;
}
}
// 处理本人是否关注 end
for ($i=0; $i < count($content_list); $i++) {
if($content_list[$i]['cover'] == null){
$content_list[$i]['cover'] = 'https://tc.pcxbc.com/kitchenscale_all/diule.jpg';
}
}
return $this->msg([
'page_now'=>$page_now,
'page_total'=>$page_total,
'content_list'=>$content_list
]);
}
public function find_by_food_action($data){
$page_now = $data['page'];
$page_total = $data['page'];
$page_num = 20;
$food_name = $data['food_name'];
$cfc = Db::connect('cfc_db');
$content_num = $cfc->table($this->kitchenscale_db_msg['cookbook'])
->where("food_type like '%$food_name%'")
->count();
$page_total = ceil($content_num/$page_num);
$content_list = $cfc->table($this->kitchenscale_db_msg['cookbook'])
->alias('cookbook')
->join($this->kitchenscale_db_msg['uploadimg'].' uploadimg','cookbook.cover = uploadimg.id','LEFT')
->where("cookbook.food_type like '%$food_name%'")
->field('cookbook.id,cookbook.title,uploadimg.pic_url as cover,cookbook.create_user_head_pic,cookbook.create_user_nickname,cookbook.like_it')
->page("$page_now,$page_num")
->select();
// 处理本人是否关注 start
$like_it_arr = [];
foreach ($content_list as $key => $value) {
array_push($like_it_arr, $value['id']);
}
$like_it_data = $cfc->table($this->kitchenscale_db_msg['collectlist'])
->where("token = '".$data['token']."' AND cookbook_id in (".implode(',',$like_it_arr).") AND is_del = 0")
->select();
$like_it_arr2 = [];
foreach ($like_it_data as $key => $value) {
array_push($like_it_arr2, $value['cookbook_id']);
}
foreach ($content_list as $key => $value) {
if(in_array($value['id'],$like_it_arr2)){
$content_list[$key]['is_like'] = 1;
}else{
$content_list[$key]['is_like'] = 0;
}
}
// 处理本人是否关注 end
for ($i=0; $i < count($content_list); $i++) {
if($content_list[$i]['cover'] == null){
$content_list[$i]['cover'] = 'https://tc.pcxbc.com/kitchenscale_all/diule.jpg';
}
}
return $this->msg([
'page_now'=>$page_now,
'page_total'=>$page_total,
'content_list'=>$content_list
]);
}
public function cookbook_details_action($data){
$cfc = Db::connect('cfc_db');
$img_arr = [];
// 查询菜谱详情
$cookbook_data = $cfc->table($this->kitchenscale_db_msg['cookbook'])->where(['id'=>$data['cookbook_id']])->find();
if(!$cookbook_data){
return $this->msg(10002,'菜谱不存在');
}
$cookbook_data['food_data'] = json_decode($cookbook_data['food_data'],true);
$cookbook_data['step_data'] = json_decode($cookbook_data['step_data'],true);
$cookbook_data_step_data_count = count($cookbook_data['step_data']);
// 设置需要的图片id
array_push($img_arr, $cookbook_data['cover']);
foreach ($cookbook_data['step_data'] as $key => $value) {
if(count($value['pic_list']) > 0){
foreach ($value['pic_list'] as $k => $v) {
if(!in_array($v, $img_arr)){
array_push($img_arr, $v);
}
}
}
}
$img_arr = implode(',',$img_arr);
// 查找需要的图片
$img_arr_data = $cfc->table($this->kitchenscale_db_msg['uploadimg'])->where("id in ($img_arr) AND is_del = 0")->field('id,pic_name,pic_url')->select();
$cookbook_img_data = [];
// 处理菜谱图片
foreach ($img_arr_data as $key => $value) {
$cookbook_img_data[$value['id']] = $value['pic_url'];
}
// 设置菜谱图片
foreach ($cookbook_data['step_data'] as $key => $value) {
$cookbook_data['step_data'][$key]['pic_list_ls'] = [];
foreach ($value['pic_list'] as $k => $v) {
if(array_key_exists($v, $cookbook_img_data)){
array_push($cookbook_data['step_data'][$key]['pic_list_ls'],$cookbook_img_data[$v]);
}else{
array_push($cookbook_data['step_data'][$key]['pic_list_ls'],'https://tc.pcxbc.com/kitchenscale_all/diule.jpg');
}
}
$cookbook_data['step_data'][$key]['pic_list'] = $cookbook_data['step_data'][$key]['pic_list_ls'];
unset($cookbook_data['step_data'][$key]['pic_list_ls']);
$cookbook_data['step_data'][$key]['step_num'] = "步骤".($key+1).'/'.$cookbook_data_step_data_count;
}
if(array_key_exists($cookbook_data['cover'], $cookbook_img_data)){
$cookbook_data['cover'] = $cookbook_img_data[$cookbook_data['cover']];
}else{
$cookbook_data['cover'] = 'https://tc.pcxbc.com/kitchenscale_all/diule.jpg';
}
// 处理关注跟收藏信息
if($data['token'] == $cookbook_data['create_user_token']){
// 如果查询跟作者一致
$cookbook_data['follow_status'] = 3;
$cookbook_data['collect_status'] = 3;
}else{
$follow_data = $cfc->table($this->kitchenscale_db_msg['followlist'])
->where([
'follow_user_token'=>$data['token'],
'being_follow_user_token'=>$cookbook_data['create_user_token'],
])
->find();
if($follow_data){
if($follow_data['is_del'] == 0){
// 如果有结果并且没被删过
$cookbook_data['follow_status'] = 1;
}else{
// 如果有结果被删过
$cookbook_data['follow_status'] = 0;
}
}else{
// 如果没结果
$cookbook_data['follow_status'] = 0;
}
$collect_data = $cfc->table($this->kitchenscale_db_msg['collectlist'])
->where([
'token'=>$data['token'],
'cookbook_id'=>$data['cookbook_id'],
])
->find();
if($collect_data){
if($collect_data['is_del'] == 0){
// 如果有结果并且没被删过
$cookbook_data['collect_status'] = 1;
}else{
// 如果有结果被删过
$cookbook_data['collect_status'] = 0;
}
}else{
// 如果没结果
$cookbook_data['collect_status'] = 0;
}
}
// 添加阅读量
$read_num = $cfc->table($this->kitchenscale_db_msg['cookbook'])->where(['id'=>$data['cookbook_id']])->setInc('read_it');
if($read_num){
$cookbook_data['read_it'] = $cookbook_data['read_it']+1;
}
unset($cookbook_data['create_user_token']);
unset($cookbook_data['create_time']);
unset($cookbook_data['cook_label']);
unset($cookbook_data['food_type']);
unset($cookbook_data['ROW_NUMBER']);
return $this->msg($cookbook_data);
// dump($cookbook_data);
}
public function cookbook_follow_action($data){
// dump($data);
$cfc = Db::connect('cfc_db');
$cookbook_data = $cfc->table($this->kitchenscale_db_msg['cookbook'])->where(['id'=>$data['cookbook_id']])->field('id,create_user_token')->find();
if(!$cookbook_data){
return $this->msg(10002,'未找到菜谱');
}
if($data['token'] == $cookbook_data['create_user_token']){
// 如果查询跟作者一致
return $this->msg(10002,'不能关注自己');
}
$follow_data = $cfc->table($this->kitchenscale_db_msg['followlist'])
->where([
'follow_user_token'=>$data['token'],
'being_follow_user_token'=>$cookbook_data['create_user_token'],
])
->find();
$follow_data_state = 0;
if($follow_data){
if($follow_data['is_del'] == 0){
// 如果当前是关注状态
$follow_data_state = 1;
}else{
$follow_data_state = 0;
}
$follow_result= $cfc->table($this->kitchenscale_db_msg['followlist'])
->where([
'follow_user_token'=>$data['token'],
'being_follow_user_token'=>$cookbook_data['create_user_token'],
])
->update(['is_del'=>$follow_data_state]);
}else{
$follow_result = $cfc->table($this->kitchenscale_db_msg['followlist'])
->insert([
'follow_user_token'=>$data['token'],
'being_follow_user_token'=>$cookbook_data['create_user_token'],
'create_time'=>date('Y-m-d H:i:s')
]);
}
if($follow_result){
return $this->msg([]);
}else{
return $this->msg(10001,'操作失败');
}
}
public function cookbook_like_action($data){
$cfc = Db::connect('cfc_db');
$cookbook_data = $cfc->table($this->kitchenscale_db_msg['cookbook'])->where(['id'=>$data['cookbook_id']])->field('id,create_user_token')->find();
if(!$cookbook_data){
return $this->msg(10002,'未找到菜谱');
}
if($data['token'] == $cookbook_data['create_user_token']){
// 如果查询跟作者一致
return $this->msg(10002,'不能收藏自己');
}
$like_data = $cfc->table($this->kitchenscale_db_msg['collectlist'])
->where([
'token'=>$data['token'],
'cookbook_id'=>$data['cookbook_id'],
])
->find();
$like_data_state = 0;
if($like_data){
if($like_data['is_del'] == 0){
// 如果当前是关注状态
$like_data_state = 1;
}else{
$like_data_state = 0;
}
// 启动事务
Db::startTrans();
try{
$cfc->table($this->kitchenscale_db_msg['collectlist'])
->where([
'token'=>$data['token'],
'cookbook_id'=>$data['cookbook_id'],
])
->update(['is_del'=>$like_data_state]);
if($like_data_state == 0){
$cfc->table($this->kitchenscale_db_msg['cookbook'])->where(['id'=>$data['cookbook_id']])->setInc('like_it');
}else{
$cfc->table($this->kitchenscale_db_msg['cookbook'])->where(['id'=>$data['cookbook_id']])->setDec('like_it');
}
// 提交事务
Db::commit();
return $this->msg([]);
} catch (\Exception $e) {
// 回滚事务
Db::rollback();
return $this->msg(10001,'操作失败');
}
}else{
// 启动事务
Db::startTrans();
try{
$cfc->table($this->kitchenscale_db_msg['collectlist'])
->insert([
'token'=>$data['token'],
'cookbook_id'=>$data['cookbook_id'],
'create_time'=>date('Y-m-d H:i:s')
]);
$cfc->table($this->kitchenscale_db_msg['cookbook'])->where(['id'=>$data['cookbook_id']])->setInc('like_it');
// 提交事务
Db::commit();
return $this->msg([]);
} catch (\Exception $e) {
// 回滚事务
Db::rollback();
return $this->msg(10001,'操作失败');
}
}
}
public function cookbook_count_weight_action($data){
$data['food_weight'] = [
[
'food_name'=>'牛肉',
'food_weight'=>'100',
'food_kcal'=>'190',
],
[
'food_name'=>'狗肉',
'food_weight'=>'100',
'food_kcal'=>'116',
],
];
foreach ($variable as $key => $value) {
if(!array_key_exists('food_name', $data['food_weight']) || !array_key_exists('food_weight', $data['food_weight']) || !array_key_exists('food_kcal', $data['food_weight'])){
return $this->msg(10001,'食材称重参数错误');
}
}
}
}

View File

@ -0,0 +1,67 @@
<?php
namespace app\KitchenScale\controller\app;
use think\Db;
class Login extends Base{
protected $code_time = 50;
// protected $token_time = 2592000;//30天的秒数
protected $default_head_pic = 'http://tc.pcxbc.com/tsf/head_pic.png';
protected $login_use_db_name = [
'1'=>'app_account_number',
];
// 加 bcadd(,,20)
// 减 bcsub(,,20)
// 乘 bcmul(,,20)
// 除 bcdiv(,,20)
################################################################接口################################################################
################################################################接口################################################################
################################################################接口################################################################
// 注册
public function login_api($data = ['account'=>123,'password'=>456]){
try {
// 你的业务逻辑
if(count(input('post.')) > 0){
$data = input('post.');
}
if(!array_key_exists('account', $data) && !array_key_exists('password', $data)){
return $this->msg(10001);
}
$return_data = $this->login_action($data);
// 成功
$this->record_api_log($data, null, $return_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'] .= "代码: " . $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);
}
}
#######################################################################action#######################################################################
public function login_action($data){
// dump($data);
$user = Db::table('admin_user_account_number')->where(["account_num"=>$data['account'],'password'=>$data['password']])->find();
// dump($user);
// die;
if($user){
return $this->msg(['token'=>$user['token']]);
}else{
return $this->msg(10004);
}
}
}

View File

@ -0,0 +1,209 @@
<?php
namespace app\KitchenScale\controller\app;
use think\Db;
class Index extends Base{
protected $code_time = 50;
// protected $token_time = 2592000;//30天的秒数
protected $default_head_pic = 'http://tc.pcxbc.com/tsf/head_pic.png';
protected $reedaw_db_msg = [
'zhanghao'=>'app_account_number',//账号表
'juese'=>'app_user_data',//角色表
'banner'=>'admin_notice_banner',//banner
'read_log'=>'admin_editor_text_like_up_log',//阅读记录
'cookbook'=>'app_user_cookbook',//菜谱表
'upload_img'=>'app_user_upload_img',//素材表
];
protected $kitchenscale_db_msg = [
'cookbook'=>'app_user_cookbook',//菜谱表
'uploadimg'=>'app_user_upload_img',//素材表
'foodlist1'=>'app_food_type_one',//素材表
'foodlist2'=>'app_food_type_two',//素材表
'foodlist3'=>'app_food_type_three',//素材表
];
// 加 bcadd(,,20)
// 减 bcsub(,,20)
// 乘 bcmul(,,20)
// 除 bcdiv(,,20)
################################################################接口################################################################
################################################################接口################################################################
################################################################接口################################################################
// 获取默认配置信息(包含:食材的分类列表)
public function get_default_config(){
// try {
$return_data = $this->get_default_config_action();
// 成功
// $this->record_api_log($data, null, $return_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'] .= "代码: " . $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);
// }
}
// 获取首页信息
public function get_homepage_information($data = ['token'=>'caadd1be045a65f30b92aa805f1de54a']){
// try {
// 你的业务逻辑
if(count(input('post.')) > 0){
$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);
}
$return_data = $this->get_homepage_information_action($data);
// 成功
$this->record_api_log($data, null, $return_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'] .= "代码: " . $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);
// }
}
#######################################################################action#######################################################################
public function get_default_config_action(){
$return_data = [
'food_list'=>[],
];
$cfc = Db::connect('cfc_db');
// 获取食材分类列表start
$foodlist1 = $cfc->table($this->kitchenscale_db_msg['foodlist1'])->where("is_del = 0")->field('id,name')->select();
$foodlist2 = $cfc->table($this->kitchenscale_db_msg['foodlist2'])->where("is_del = 0")->field('id,name,one_id')->select();
$foodlist3 = $cfc->table($this->kitchenscale_db_msg['foodlist3'])->where("is_del = 0")->field('id,name,two_id,kcal')->select();
// dump($foodlist3);
foreach ($foodlist1 as $key => $value) {
unset($foodlist1[$key]['ROW_NUMBER']);
$foodlist1[$key]['list'] = [];
foreach ($foodlist2 as $k => $v) {
$foodlist2[$k]['list'] = [];
foreach ($foodlist3 as $k3 => $v3) {
if($v3['two_id'] == $v['id']){
unset($foodlist3[$k3]['ROW_NUMBER']);
array_push($foodlist2[$k]['list'],$foodlist3[$k3]);
// unset($foodlist3[$k3]);
}
}
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
return $this->msg($return_data);
}
public function get_homepage_information_action($data){
$return_data = [
'account'=>[],
'banner'=>[],
'content'=>[
'label_list'=>[],
'content_list'=>[],
],
];
$cfc = Db::connect('cfc_db');
// 获取账号下信息以及用户信息
$user_account = Db::table($this->reedaw_db_msg['zhanghao'])
->alias('zhanghao')
->join($this->reedaw_db_msg['juese'].' juese','zhanghao.id = juese.aan_id','LEFT')
->where(["zhanghao.token"=>$data['token'],'juese.is_del'=>0])
// ->field('juese.id as aud_id,juese.nickname,juese.birthday,juese.gender,juese.last_update_time,juese.grade,juese.head_pic,juese.weight,juese.height,juese.identity_name,juese.address,juese.identity_id,juese.weight')
->field('juese.id as aud_id,juese.nickname,juese.birthday,juese.gender,juese.grade,juese.head_pic')
->select();
$return_data['account'] = $user_account;
// 获取banner
$banner_list = Db::table($this->reedaw_db_msg['banner'])
->where("is_del = 0 AND scene_data IN (21)")
->order('sort_num desc,id desc')
->field('id,title,pic,type,jump_url,create_time,scene_data,sort_num,parameter_data')
->select();
foreach ($banner_list as $key => $value) {
if($value['type'] == '1'){
$banner_list[$key]['type'] = 'h5';
$banner_list[$key]['id'] = $value['parameter_data'];
}else{
$banner_list[$key]['type'] = 'wechat';
// 提取查询字符串部分(?后面的部分)
$queryString = substr($banner_list[$key]['jump_url'], strpos($banner_list[$key]['jump_url'], '?') + 1);
// 使用parse_str解析查询字符串
$params = [];
parse_str($queryString, $params);
// 提取appid和path的值
$appid = isset($params['appid']) ? $params['appid'] : null;
$path = isset($params['path']) ? $params['path'] : null;
$banner_list[$key]['appid'] = $appid;
$banner_list[$key]['path'] = $path;
// 重新定义跳转链接为中间页
$banner_list[$key]['jump_url'] = "https://tc.pcxbc.com/open_wechat_content";
}
unset($banner_list[$key]['scene_data']);
unset($banner_list[$key]['sort_num']);
unset($banner_list[$key]['ROW_NUMBER']);
unset($banner_list[$key]['parameter_data']);
}
$return_data['banner'] = $banner_list;
// 获取菜谱列表
$label_list = $cfc->table($this->kitchenscale_db_msg['cookbook'])->group('cook_label')->field('cook_label,count(*) as num')->select();
if(count($label_list) <= 0){
$return_data['content']['label_list'] = [];
$return_data['content']['content_list'] = [];
return $this->msg($return_data);
}
$content_list = $cfc->table($this->kitchenscale_db_msg['cookbook'])
->alias('zhanghao')
->join($this->kitchenscale_db_msg['uploadimg'].' uploadimg','zhanghao.cover = uploadimg.id','LEFT')
->where(['zhanghao.cook_label'=>$label_list[0]['cook_label']])
->field('zhanghao.title,uploadimg.pic_url as cover,zhanghao.create_user_head_pic,zhanghao.create_user_nickname,zhanghao.like_it')
->page("1,20")
->select();
$return_data['content']['label_list'] = $label_list;
for ($i=0; $i < count($content_list); $i++) {
if($content_list[$i]['cover'] == null){
$content_list[$i]['cover'] = 'https://tc.pcxbc.com/kitchenscale_all/diule.jpg';
}
}
$return_data['content']['content_list'] = $content_list;
return $this->msg($return_data);
}
}

View File

@ -0,0 +1,67 @@
<?php
namespace app\KitchenScale\controller\app;
use think\Db;
class Login extends Base{
protected $code_time = 50;
// protected $token_time = 2592000;//30天的秒数
protected $default_head_pic = 'http://tc.pcxbc.com/tsf/head_pic.png';
protected $login_use_db_name = [
'1'=>'app_account_number',
];
// 加 bcadd(,,20)
// 减 bcsub(,,20)
// 乘 bcmul(,,20)
// 除 bcdiv(,,20)
################################################################接口################################################################
################################################################接口################################################################
################################################################接口################################################################
// 注册
public function login_api($data = ['account'=>123,'password'=>456]){
try {
// 你的业务逻辑
if(count(input('post.')) > 0){
$data = input('post.');
}
if(!array_key_exists('account', $data) && !array_key_exists('password', $data)){
return $this->msg(10001);
}
$return_data = $this->login_action($data);
// 成功
$this->record_api_log($data, null, $return_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'] .= "代码: " . $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);
}
}
#######################################################################action#######################################################################
public function login_action($data){
// dump($data);
$user = Db::table('admin_user_account_number')->where(["account_num"=>$data['account'],'password'=>$data['password']])->find();
// dump($user);
// die;
if($user){
return $this->msg(['token'=>$user['token']]);
}else{
return $this->msg(10004);
}
}
}

View File

@ -248,7 +248,7 @@ class Base extends Controller{
if($info){
$insert_data = [
'url_data'=>"https://tc.pcxbc.com/upload_pic/".$new_filename,
'name'=>$name,
'name'=>$new_filename,
'create_time'=>date('Y-m-d H:i:s'),
];
$pic_result = Db::table('admin_pic_manage')->insertGetId($insert_data);

View File

@ -0,0 +1,98 @@
<?php
namespace app\admin\controller;
use think\Controller;
use think\Db;
use think\Log;
use app\admin\controller\Download;
class Business extends Base{
protected $page_num = 10;
protected $file_max_pic = 1024*1024*5;//xxxMB
protected $information_msg_list_arr = [
'1' => '身高管理',
'2' => '体重管理',
'3' => '肺活训练',
'4' => '跳绳训练',
'5' => '中考体测',
'6' => '公告',
];
###################################################banner图管理start###################################################
###################################################banner图管理start###################################################
###################################################banner图管理start###################################################
public function business_index($page = 1){
$data = input();
$pd = true;
$parameter = [];
if(array_key_exists('tt', $data)){
$page = $data['page_num'];
unset($data['page_num']);
unset($data['tt']);
$pd = false;
// if($data['status_num'] === "0" || $data['status_num'] === "1"){
// $parameter['is_del'] = $data['status_num'];
// }
// if($data['tel']){
// $parameter['tel'] = $data['tel'];
// }
// if($data['email']){
// $parameter['email'] = $data['email'];
// }
// if($data['s_time']){
// $parameter['create_time'] = ['>=',$data['s_time']];
// }
// if($data['e_time']){
// $parameter['create_time'] = ['<=',$data['e_time']];
// }
}
$num = Db::table('admin_business_cooperation_log')->where($parameter)->count();
$result = Db::table('admin_business_cooperation_log')->where($parameter)->order('id desc')->page($page,$this->page_num)->select();
// dump($result);
// die;
if(!$pd){
$return_result['num'] = $num;
$return_result['data'] = $result;
return $this->msg(0,'success',$return_result);
}
$this->assign([
'result' => $result,
'num' => $num,
]);
return $this->fetch();
}
// 下载表单
public function business_download(){
$result = Db::table('admin_business_cooperation_log')->select();
for ($i=0; $i < count($result); $i++) {
unset($result[$i]['ROW_NUMBER']);
}
// ->field("name as '客户姓名',tel as '联系电话',company as '公司名称',intention_data as '合作意向',notes_data as '备注',create_time as '添加时间'")
$execl_data = [
['客户姓名','联系电话','公司名称','合作意向','备注','添加时间'],
];
for ($i=0; $i < count($result); $i++) {
$temporary_arr = [];
array_push($temporary_arr, $result[$i]['name']);
array_push($temporary_arr, $result[$i]['tel']);
array_push($temporary_arr, $result[$i]['company']);
array_push($temporary_arr, $result[$i]['intention_data']);
array_push($temporary_arr, $result[$i]['notes_data']);
array_push($temporary_arr, $result[$i]['create_time']);
array_push($execl_data, $temporary_arr);
}
$download = new Download();
$download->downloadExcel($execl_data, '用户信息.xlsx');
}
}

View File

@ -204,4 +204,70 @@ class Device extends Base{
// return $this->msg(10002);
// }
}
################################################################以下为设备提供接口################################################################
################################################################以下为设备提供接口################################################################
################################################################以下为设备提供接口################################################################
public function device_request_api(){
// $data = input();
$rawData = file_get_contents('php://input'); // 获取原始请求体
// $params = explode(',', trim($rawData, '{}')); // 假设参数是用逗号分隔的,并且被大括号包裹
// // 现在$params是一个数组包含了['03', '180.0', '65.1']
// $param1 = $params[0]; // 获取第一个参数
// $param2 = $params[1]; // 获取第二个参数,注意转换为浮点数或保持字符串形式
// $param3 = $params[2]; // 获取第三个参数
// dump($data);
// dump(json_encode($data));
// dump($rawData);
$content = json_encode($rawData);
// dump($content);
// die;
$result = Db::table('app_device_log_test')->insert(['content'=>$content,'create_time'=>date('Y-m-d H:i:s')]);
if($result){
return $this->msg(0,'success');
}else{
return $this->msg(10002,'存储失败');
}
}
public function see_device_msg(){
$result = Db::table('app_device_log_test')->select();
if(count($result) <= 0){
echo "没有找到请求记录";
}
$neirong = '';
foreach ($result as $key => $value) {
$neirong = $neirong.'第'.($key+1).'次请求</br>本次请求参数为:'.$value['content'].'</br>'.'请求时间为:'.$value['create_time']."</br></br></br>";
// $temporary_arr1 = json_decode($value['content'],true);
// if(count($temporary_arr1) == 0){
// $temporary_arr2 = '请求参数为:</br>'."本次未发送请求参数</br>";
// }else{
// $temporary_arr2 = '请求参数为:</br>';
// }
// foreach ($temporary_arr1 as $k => $v) {
// $temporary_arr2 = $temporary_arr2.$k."(参数名):".$v."(参数值)</br>";
// }
// $neirong = $neirong.$temporary_arr2.'请求时间为:'.$value['create_time']."</br></br></br>";
}
echo $neirong;
}
}

View File

@ -0,0 +1,141 @@
<?php
namespace app\admin\controller;
use think\Controller;
use think\Db;
use app\bj\controller\Common;
use think\Log;
use \think\Validate;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Style\Border;
use PhpOffice\PhpSpreadsheet\Style\Fill;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
class Download extends Controller{
protected $ceshiyong_token = 'caadd1be045a65f30b92aa805f1de54a';
// // 测试后端判断是否微信环境
// function is_wechat() {
// // 获取 User-Agent 字符串
// $userAgent = $_SERVER['HTTP_USER_AGENT'];
// // 检查 User-Agent 字符串中是否包含 "MicroMessenger"
// if (strpos($userAgent, 'MicroMessenger') !== false) {
// echo "是微信浏览器";
// }else{
// echo "不是微信浏览器";
// }
// }
/**
* 下载 Excel 文件
*
* @param array $data 要导出的数据
* @param string $filename 文件名
* @return void
*/
public function downloadExcel($ceshiyong_data, $filename = 'data.xlsx')
{
// 创建一个新的 Spreadsheet 对象
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
// 获取列数
$columnCount = count($ceshiyong_data[0]);
// 添加标题到工作表中
$titles = $ceshiyong_data[0];
for ($colIndex = 0; $colIndex < $columnCount; $colIndex++) {
$sheet->setCellValueByColumnAndRow($colIndex + 1, 1, $titles[$colIndex]);
}
// 添加数据到工作表中
$data = array_slice($ceshiyong_data, 1);
foreach ($data as $rowIndex => $rowData) {
for ($colIndex = 0; $colIndex < $columnCount; $colIndex++) {
$sheet->setCellValueByColumnAndRow($colIndex + 1, $rowIndex + 2, $rowData[$colIndex]);
}
}
// 设置表头样式
$headerStyle = [
'font' => [
'bold' => true,
],
'fill' => [
'fillType' => Fill::FILL_SOLID,
'startColor' => [
'argb' => 'FFFFC000', // 橙色
],
],
'alignment' => [
'horizontal' => Alignment::HORIZONTAL_CENTER,
],
'borders' => [
'allBorders' => [
'borderStyle' => Border::BORDER_THIN,
],
],
];
$sheet->getStyle('A1:' . $this->getExcelColumnName($columnCount) . '1')->applyFromArray($headerStyle);
// 设置所有内容居中
$allContentStyle = [
'alignment' => [
'horizontal' => Alignment::HORIZONTAL_CENTER,
],
'borders' => [
'allBorders' => [
'borderStyle' => Border::BORDER_THIN,
],
],
];
$sheet->getStyle('A1:' . $this->getExcelColumnName($columnCount) . (count($ceshiyong_data) + 1))->applyFromArray($allContentStyle);
// 设置斑马纹效果
$rowCount = count($ceshiyong_data) - 1; // 数据行数
for ($rowIndex = 1; $rowIndex <= $rowCount; $rowIndex++) {
$row = $rowIndex + 1; // 数据行从第二行开始
$rowStyle = [
'fill' => [
'fillType' => Fill::FILL_SOLID,
'startColor' => [
'argb' => ($rowIndex % 2 == 0) ? 'FFDDDDDD' : 'FFFFFFFF', // 偶数行浅灰色,奇数行白色
],
],
];
$sheet->getStyle('A' . $row . ':' . $this->getExcelColumnName($columnCount) . $row)->applyFromArray($rowStyle);
}
// 设置响应头以触发文件下载
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="' . $filename . '"');
header('Cache-Control: max-age=0');
// 保存并输出 Excel 文件
$writer = new Xlsx($spreadsheet);
$writer->save('php://output');
exit;
}
/**
* 获取 Excel 列名
*
* @param int $index 列索引从1开始
* @return string Excel 列名
*/
private function getExcelColumnName($index)
{
$columnName = '';
while ($index > 0) {
$remainder = ($index - 1) % 26;
$columnName = chr(65 + $remainder) . $columnName;
$index = intval(($index - 1) / 26);
}
return $columnName;
}
}

View File

@ -74,6 +74,8 @@ class Editortext extends Base{
public function model_content(){
$data = input();
// dump($data);
// die;
// $data['id'] = '3';
if(!array_key_exists('id', $data)){
return $this->msg(10001,'id缺失');

View File

@ -28,7 +28,7 @@ class Notice extends Base{
$data = input();
$pd = true;
$parameter = [];
$parameter['scene_data'] = 3;
// $parameter['scene_data'] = 3;
if(array_key_exists('tt', $data)){
$page = $data['page_num'];
unset($data['page_num']);
@ -90,7 +90,7 @@ class Notice extends Base{
'title' => $data['title'],
'pic' => $data['banner_img'],
'type' => $data['type'],
'jump_url' => '',
'jump_url' => $data['jump_url'],
'parameter_data' => $data['parameter_data'],
'create_time' => date('Y-m-d H:i:s'),
'scene_data' => $data['scene_data'],
@ -98,9 +98,9 @@ class Notice extends Base{
$pic_data = Db::table('admin_pic_manage')->where(['id'=>$action_data['pic']])->find();
$action_data['pic'] = $pic_data['url_data'];
if($action_data['type'] == 1){
$action_data['jump_url'] = "https://tc.pcxbc.com/editortext/model_content?id=".$action_data['parameter_data'];
$action_data['jump_url'] = "https://tc.pcxbc.com/editortext/model_content";
}else if($action_data['type'] == 2){
$action_data['jump_url'] = $data['jump_url'];
$action_data['jump_url'] = "weixin://dl/business/?appid=".$data['parameter_data']."&path=".$data['jump_url'];
}else{
return $this->msg(10002,'选择类型错误');
}

View File

@ -0,0 +1,237 @@
<!DOCTYPE html>
<html class="x-admin-sm">
<head>
<meta charset="UTF-8">
<title>添加banner</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />
<link rel="stylesheet" href="/x_admin/css/font.css">
<link rel="stylesheet" href="/x_admin/css/xadmin.css">
<script type="text/javascript" src="/x_admin/lib/layui/layui.js" charset="utf-8"></script>
<script type="text/javascript" src="/x_admin/js/xadmin.js"></script>
<script type="text/javascript" src="/x_admin/js/jq.js"></script>
</head>
<body>
<div class="layui-fluid">
<div class="layui-row" id="app_all">
<form action="" method="post" class="layui-form layui-form-pane">
<div class="layui-form-item">
<label for="title_v" class="layui-form-label">
<span class="x-red"></span>标题描述
</label>
<div class="layui-input-inline" style="width: 80%;">
<input type="text" id="title_v" name="title_v" lay-verify="title_v" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label for="pic_v" class="layui-form-label">
<span class="x-red"></span>选择封面
</label>
<div class="layui-input-inline">
<div class="layui-btn" onclick="xadmin.open('图片管理','/admin/pic','80%','80%')">点击选择</div>
<!-- <input type="file" id="upload_file_app" accept="image/*" lay-verify="upload_file_app" name="data_excel" class="layui-btn layui-btn-normal layui-btn-mini"> -->
</div>
</div>
<div class="layui-form-item">
<label for="yulan_v" class="layui-form-label">
<span class="x-red"></span>预览
</label>
<div class="layui-input-inline">
<img id="preview_img" style="max-width:500px;box-shadow: 0px 0px 1px;" src="" alt="">
<input type="hidden" name="banner_img" id="banner_img" lay-verify="banner_img" value=""></input>
</div>
</div>
<div class="layui-form-item">
<label for="scene_data" class="layui-form-label">
<span class="x-red"></span>选择场景
</label>
<div class="layui-input-inline" style="width: 80%;">
<select id="scene_data" name="scene_data" lay-filter="scene_data" lay-verify="scene_data">
<option value="0">请选择使用场景</option>
<option value="1">首屏弹窗</option>
<option value="2">滚动公告</option>
<option value="3">首页banner</option>
</select>
</div>
</div>
<div class="layui-form-item">
<label for="data_type" class="layui-form-label">
<span class="x-red"></span>选择类型
</label>
<div class="layui-input-inline" style="width: 80%;">
<select id="data_type" name="data_type" lay-filter="data_type" lay-verify="data_type">
<option value="0">请选择跳转类型</option>
<option value="1">站内文章</option>
<option value="2">微信小程序</option>
</select>
</div>
</div>
<div class="layui-form-item">
<label for="parameter_data" class="layui-form-label">
<span class="x-red"></span>填写关键参数
</label>
<div class="layui-input-inline" style="width: 80%;">
<input type="text" id="parameter_data" name="parameter_data" lay-verify="parameter_data" autocomplete="off" class="layui-input" onfocus="pd_data_type()">
</div>
</div>
<div class="layui-form-item">
<label for="jump_url" class="layui-form-label">
<span class="x-red"></span>页面路径
</label>
<div class="layui-input-inline" style="width: 80%;">
<input type="text" id="jump_url" name="jump_url" lay-verify="jump_url" autocomplete="off" class="layui-input" placeholder="若选择站内文章,则无需填写该项">
</div>
</div>
<div class="layui-form-item" style="display: flex;flex-direction: row;justify-content: center;">
<button class="layui-btn" lay-filter="add" lay-submit="">增加</button>
</div>
</form>
</div>
</div>
<script>
var ts = true
var pic_data = []
function receiveParamFromIframe(param) {
pic_data = param
if(pic_data.length > 0){
var img = document.getElementById('preview_img');
img.src = pic_data[1]; // 设置图片预览的src属性
img.style.display = 'block'; // 显示图片预览
$('#banner_img').val(pic_data[0])
}
}
function receiveParamFromIframe_information(param) {
$('#parameter_data').val(param);
layer.msg('已选择文章ID为'+param)
}
function pd_data_type(){
console.log($('#data_type').val())
if($('#data_type').val() == 1){
xadmin.open('资讯简易列表','/notice/information_msg_list','80%','80%')
$('#parameter_data').blur()
}else if($('#data_type').val() == 2){
layer.msg('请填写微信小程序APPID')
$('#jump_url').attr('placeholder', '填写页面路径前请先确认已经配置小程序的URL Scheme');
if(ts){
layer.alert(
"您选择了小程序类型填写页面路径前请先确认已经配置小程序的URL Scheme。小程序后台->账号设置->隐私与安全->明文scheme拉起此小程序->配置->在“小程序 path”中添加页面路径多个路径以回车换行的方式书写",
{icon: 6}
);
ts = false;
}
}else{
layer.msg('请选择跳转类型')
}
}
</script>
<script>
var form
layui.use(['form'], function () {
form = layui.form;
form.verify({
title_v: function(value) {
if (value == '') {
return '请先填写标题描述';
}
},
banner_img: function(value) {
if (value == '') {
return '请先选择封面';
}
},
data_type: function(value) {
if (value == 0) {
return '请先选择类型';
}
},
scene_data: function(value) {
if (value == 0) {
return '请先选择使用场景';
}
},
parameter_data: function(value) {
if (value == 0) {
return '请先填写关键参数信息';
}
},
jump_url: function(value) {
if ($('#data_type').val() == 2) {
if($('#jump_url').val() == ''){
return '请先填写微信小程序页面路径';
}
}
},
});
//监听提交
form.on('submit(add)',function(data) {
//发异步把数据提交给php
add_data()
return false;
});
});
// 功能性~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function add_data(){
load()
var data = {
'title':$('#title_v').val(),
'banner_img':$('#banner_img').val(),
'type':$('#data_type').val(),
'scene_data':$('#scene_data').val(),
'parameter_data':$('#parameter_data').val(),
'jump_url':$('#jump_url').val(),
'action_type':'add',
}
$.ajax({
url: "banner_add_or_update_action", //请求的url地址s
dataType: "json", //返回格式为json
async: true,//请求是否异步默认为异步这也是ajax重要特性
data: data, //参数值
type: "POST", //请求方式
success:function(req){
c_load()
if(req.code == 0){
layer.alert("增加成功", {icon: 6},function() {
//关闭当前frame
xadmin.close();
// 可以对父窗口进行刷新
xadmin.father_reload();
});
}else{
layer.alert("增加失败"+req.msg, {icon: 6},function() {
//关闭当前frame
xadmin.close();
// 可以对父窗口进行刷新
xadmin.father_reload();
});
}
},
error:function(){
//请求出错处理
pd = true
}
});
}
//加载提示开启
function load() {
var index = layer.load(1, {
shade: [0.1, '#fff'] //0.1透明度的白色背景
});
}
// 关闭加载提示
function c_load() {
layer.close(layer.index)
}
</script>
</body>
</html>

View File

@ -0,0 +1,265 @@
<!DOCTYPE html>
<html class="x-admin-sm">
<head>
<meta charset="UTF-8">
<title>添加banner</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />
<link rel="stylesheet" href="/x_admin/css/font.css">
<link rel="stylesheet" href="/x_admin/css/xadmin.css">
<script type="text/javascript" src="/x_admin/lib/layui/layui.js" charset="utf-8"></script>
<script type="text/javascript" src="/x_admin/js/xadmin.js"></script>
<script type="text/javascript" src="/x_admin/js/jq.js"></script>
</head>
<body>
<div class="layui-fluid">
<div class="layui-row" id="app_all">
<form action="" method="post" class="layui-form layui-form-pane">
<div class="layui-form-item">
<label for="title_v" class="layui-form-label">
<span class="x-red"></span>标题描述
</label>
<div class="layui-input-inline" style="width: 80%;">
<input type="text" id="title_v" name="title_v" lay-verify="title_v" autocomplete="off" class="layui-input" value="{$result.title}">
</div>
</div>
<div class="layui-form-item">
<label for="pic_v" class="layui-form-label">
<span class="x-red"></span>选择封面
</label>
<div class="layui-input-inline">
<div class="layui-btn" onclick="xadmin.open('图片管理','/admin/pic','80%','80%')">点击选择</div>
<!-- <input type="file" id="upload_file_app" accept="image/*" lay-verify="upload_file_app" name="data_excel" class="layui-btn layui-btn-normal layui-btn-mini"> -->
</div>
</div>
<div class="layui-form-item">
<label for="yulan_v" class="layui-form-label">
<span class="x-red"></span>预览
</label>
<div class="layui-input-inline">
<img id="preview_img" style="max-width:500px;box-shadow: 0px 0px 1px;" src="{$result.pic}" alt="">
<input type="hidden" name="banner_img" id="banner_img" lay-verify="banner_img" value="{$result.pic_id}"></input>
</div>
</div>
<div class="layui-form-item">
<label for="scene_data" class="layui-form-label">
<span class="x-red"></span>选择场景
</label>
<div class="layui-input-inline" style="width: 80%;">
<select id="scene_data" name="scene_data" lay-filter="scene_data" lay-verify="scene_data">
{if condition="$result.type == 1"}
<option value="0">请选择使用场景</option>
<option value="1" selected>首屏弹窗</option>
<option value="2">滚动公告</option>
<option value="3">首页banner</option>
{elseif condition="$result.type == 2"/}
<option value="0">请选择使用场景</option>
<option value="1">首屏弹窗</option>
<option value="2" selected>滚动公告</option>
<option value="3">首页banner</option>
{elseif condition="$result.type == 3"/}
<option value="0">请选择使用场景</option>
<option value="1">首屏弹窗</option>
<option value="2">滚动公告</option>
<option value="3" selected>首页banner</option>
{else /}
<option value="0" selected>请选择使用场景</option>
<option value="1">首屏弹窗</option>
<option value="2">滚动公告</option>
<option value="3">首页banner</option>
{/if}
</select>
</div>
</div>
<div class="layui-form-item">
<label for="data_type" class="layui-form-label">
<span class="x-red"></span>选择类型
</label>
<div class="layui-input-inline" style="width: 80%;">
<select id="data_type" name="data_type" lay-filter="data_type" lay-verify="data_type">
{if condition="$result.type == 1"}
<option value="0">请选择跳转类型</option>
<option value="1" selected>站内文章</option>
<option value="2">微信小程序</option>
{elseif condition="$result.type == 2"/}
<option value="0">请选择跳转类型</option>
<option value="1">站内文章</option>
<option value="2" selected>微信小程序</option>
{else /}
<option value="0" selected>请选择跳转类型</option>
<option value="1">站内文章</option>
<option value="2">微信小程序</option>
{/if}
</select>
</div>
</div>
<div class="layui-form-item">
<label for="parameter_data" class="layui-form-label">
<span class="x-red"></span>填写关键参数
</label>
<div class="layui-input-inline" style="width: 80%;">
<input type="text" id="parameter_data" name="parameter_data" lay-verify="parameter_data" autocomplete="off" class="layui-input" onfocus="pd_data_type()" value="{$result.parameter_data}">
</div>
</div>
<div class="layui-form-item">
<label for="jump_url" class="layui-form-label">
<span class="x-red"></span>页面路径
</label>
<div class="layui-input-inline" style="width: 80%;">
<input type="text" id="jump_url" name="jump_url" lay-verify="jump_url" autocomplete="off" class="layui-input" placeholder="若选择站内文章,则无需填写该项" value="{$result.jump_url}">
</div>
</div>
<div class="layui-form-item" style="display: flex;flex-direction: row;justify-content: center;">
<button class="layui-btn" lay-filter="add" lay-submit="">修改</button>
</div>
</form>
</div>
</div>
<script>
var ts = true
var data_id = "{$result.id}"
var pic_data = []
function receiveParamFromIframe(param) {
pic_data = param
if(pic_data.length > 0){
var img = document.getElementById('preview_img');
img.src = pic_data[1]; // 设置图片预览的src属性
img.style.display = 'block'; // 显示图片预览
$('#banner_img').val(pic_data[0])
}
}
function receiveParamFromIframe_information(param) {
$('#parameter_data').val(param);
layer.msg('已选择文章ID为'+param)
}
function pd_data_type(){
console.log($('#data_type').val())
if($('#data_type').val() == 1){
xadmin.open('资讯简易列表','/notice/information_msg_list','80%','80%')
$('#parameter_data').blur()
}else if($('#data_type').val() == 2){
layer.msg('请填写微信小程序APPID')
if(ts){
layer.alert(
"您选择了小程序类型填写页面路径前请先确认已经配置小程序的URL Scheme。小程序后台->账号设置->隐私与安全->明文scheme拉起此小程序->配置->在“小程序 path”中添加页面路径多个路径以回车换行的方式书写",
{icon: 6}
);
ts = false;
}
}else{
layer.msg('请选择跳转类型')
}
}
</script>
<script>
var form
layui.use(['form'], function () {
form = layui.form;
form.verify({
title_v: function(value) {
if (value == '') {
return '请先填写标题描述';
}
},
banner_img: function(value) {
if (value == '') {
return '请先选择封面';
}
},
data_type: function(value) {
if (value == 0) {
return '请先选择类型';
}
},
scene_data: function(value) {
if (value == 0) {
return '请先选择使用场景';
}
},
parameter_data: function(value) {
if (value == 0) {
return '请先填写关键参数信息';
}
},
jump_url: function(value) {
if ($('#data_type').val() == 2) {
if($('#jump_url').val() == ''){
return '请先填写微信小程序页面路径';
}
}
},
});
//监听提交
form.on('submit(add)',function(data) {
//发异步把数据提交给php
add_data()
return false;
});
});
// 功能性~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function add_data(){
load()
var data = {
'id':data_id,
'title':$('#title_v').val(),
'banner_img':$('#banner_img').val(),
'type':$('#data_type').val(),
'scene_data':$('#scene_data').val(),
'parameter_data':$('#parameter_data').val(),
'jump_url':$('#jump_url').val(),
'action_type':'update',
}
$.ajax({
url: "banner_add_or_update_action", //请求的url地址s
dataType: "json", //返回格式为json
async: true,//请求是否异步默认为异步这也是ajax重要特性
data: data, //参数值
type: "POST", //请求方式
success:function(req){
c_load()
if(req.code == 0){
layer.alert("修改成功", {icon: 6},function() {
//关闭当前frame
xadmin.close();
// 可以对父窗口进行刷新
xadmin.father_reload();
});
}else{
layer.alert("修改失败"+req.msg, {icon: 6},function() {
//关闭当前frame
xadmin.close();
// 可以对父窗口进行刷新
xadmin.father_reload();
});
}
},
error:function(){
//请求出错处理
pd = true
}
});
}
//加载提示开启
function load() {
var index = layer.load(1, {
shade: [0.1, '#fff'] //0.1透明度的白色背景
});
}
// 关闭加载提示
function c_load() {
layer.close(layer.index)
}
</script>
</body>
</html>

View File

@ -0,0 +1,212 @@
<!DOCTYPE html>
<html class="x-admin-sm">
<head>
<meta charset="UTF-8">
<title>banner图管理</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />
<link rel="stylesheet" href="/x_admin/css/font.css">
<link rel="stylesheet" href="/x_admin/css/xadmin.css">
<script src="/x_admin/lib/layui/layui.js" charset="utf-8"></script>
<script type="text/javascript" src="/x_admin/js/xadmin.js"></script>
<style>
/* th{
min-width:30px;
} */
</style>
</head>
<body>
<div class="x-nav">
<span class="layui-breadcrumb">
<a href="">首页</a>
<a href="">演示</a>
<a>
<cite>导航元素</cite></a>
</span>
<a class="layui-btn layui-btn-small" style="line-height:1.6em;margin-top:3px;float:right" onclick="location.reload()" title="刷新">
<i class="layui-icon layui-icon-refresh" style="line-height:30px"></i></a>
</div>
<div class="layui-fluid">
<div class="layui-row layui-col-space15">
<div class="layui-col-md12">
<div class="layui-card">
<!-- <div class="layui-card-body ">
<form class="layui-form layui-col-space5">
<div class="layui-inline layui-show-xs-block">
<input class="layui-input" autocomplete="off" placeholder="开始日" name="start" id="s_time">
</div>
<div class="layui-inline layui-show-xs-block">
<input class="layui-input" autocomplete="off" placeholder="截止日" name="end" id="e_time">
</div>
<div class="layui-inline layui-show-xs-block">
<input type="text" name="username" placeholder="请输入用户手机" autocomplete="off" class="layui-input" id="tel">
</div>
<div class="layui-inline layui-show-xs-block">
<input type="text" name="username" placeholder="请输入用户邮箱" autocomplete="off" class="layui-input" id="email">
</div>
<div class="layui-input-inline layui-show-xs-block">
<select name="contrller" id="status_num">
<option value="">状态</option>
<option value="0">启用</option>
<option value="1">停用</option>
</select>
</div>
<div class="layui-inline layui-show-xs-block">
<div class="layui-btn" lay-submit="" lay-filter="sreach" onclick="find('y')"><i class="layui-icon">&#xe615;</i></div>
</div>
</form>
</div> -->
<div class="layui-card-header">
<!-- <button class="layui-btn layui-btn-danger" onclick="delAll()"><i class="layui-icon"></i>批量停用</button> -->
<!-- <button class="layui-btn" onclick="xadmin.open('添加用户','/appversion/app_add','100%','100%')"><i class="layui-icon"></i>添加</button> -->
<!-- <button class="layui-btn" onclick="xadmin.open('下载execl','/business/business_download','80%','80%')">下载execl</button> -->
<a href="/business/business_download"><button class="layui-btn">下载execl</button></a>
</div>
<div class="layui-card-body layui-table-body layui-table-main">
<table class="layui-table layui-form">
<thead>
<tr>
<th style="min-width: 30px;width:50px;">ID</th>
<th>客户姓名</th>
<th>联系电话</th>
<th>公司名称</th>
<th>合作意向</th>
<th>备注</th>
<th>添加时间</th>
</tr>
</thead>
<tbody id='content'>
{volist name="result" id="vo"}
<tr>
<td>{$vo.id}</td>
<td>{$vo.name}</td>
<td>{$vo.tel}</td>
<td>{$vo.company}</td>
<td>{$vo.intention_data}</td>
<td>{$vo.notes_data}</td>
<td>{$vo.create_time}</td>
</tr>
{/volist}
</tbody>
</table>
</div>
<div class="layui-card-body ">
<div id="page" style="text-align: center;">
</div>
</div>
</div>
</div>
</div>
</div>
</body>
<script>
var page_num;
var laypage;
var all_page = "{$num}";
layui.use('laypage', function () {
laypage = layui.laypage;
//执行一个laypage实例
laypage.render({
elem: 'page',
count: all_page, //数据总数,从服务端得到
limit: 10,
groups:10,
jump: function (obj, first) {
//首次不执行
if (!first) {
//obj包含了当前分页的所有参数比如
console.log(obj.curr); //得到当前页,以便向服务端请求对应页的数据。
console.log(obj.limit); //得到每页显示的条数
page_num = obj.curr;
find("n")
}
}
});
});
function find(pd) {
if(!page_num || pd == 'y'){
page_num = 1;
}
page({
"page_num":page_num,
"tt":1},pd);
}
function page(data,pd) {
console.log(data)
load()
$.ajax({
url: "business_index", //请求的url地址s
dataType: "json", //返回格式为json
async: true,//请求是否异步默认为异步这也是ajax重要特性
data: data, //参数值
type: "POST", //请求方式
success: function (req) {
console.log(req)
c_load();
if (req['code'] == 0) {
var str,str_s,str_c,str_all="";
for (let i = 0; i < req['data']['data'].length; i++) {
str_c = "<tr>"+
"<td>"+ req['data']['data'][i]['id'] +"</td>"+
"<td>"+ req['data']['data'][i]['name'] +"</td>"+
"<td>"+ req['data']['data'][i]['tel'] +"</td>"+
"<td>"+ req['data']['data'][i]['company'] +"</td>"+
"<td>"+ req['data']['data'][i]['intention_data'] +"</td>"+
"<td>"+ req['data']['data'][i]['notes_data'] +"</td>"+
"<td>"+ req['data']['data'][i]['create_time'] +"</td>"+
+'</tr>'
str_all = str_all+str_c;
}
$('#content').html(str_all);
form.render();
if(pd == 'y'){
$("#page").html("")
laypage.render({
elem: 'page',
count: req['data']['num'], //数据总数,从服务端得到
limit: 10,
groups:10,
jump: function (obj, first) {
//首次不执行
if (!first) {
//obj包含了当前分页的所有参数比如
console.log(obj.curr); //得到当前页,以便向服务端请求对应页的数据。
console.log(obj.limit); //得到每页显示的条数
page_num = obj.curr;
// page({"page":page_num,"tt":1});
find("n")
}
}
});
}
} else {
layer.msg(req['msg'])
}
},
error: function () {
//请求出错处理
}
});
}
//加载提示开启
function load() {
var index = layer.load(1, {
shade: [0.1, '#fff'] //0.1透明度的白色背景
});
}
// 关闭加载提示
function c_load() {
layer.close(layer.index)
}
</script>
</html>

View File

@ -0,0 +1,397 @@
<!DOCTYPE html>
<html class="x-admin-sm">
<head>
<meta charset="UTF-8">
<title>设备管理_add</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />
<link rel="stylesheet" href="/x_admin/css/font.css">
<link rel="stylesheet" href="/x_admin/css/xadmin.css">
<script type="text/javascript" src="/x_admin/lib/layui/layui.js" charset="utf-8"></script>
<script type="text/javascript" src="/x_admin/js/xadmin.js"></script>
<script type="text/javascript" src="/x_admin/js/jq.js"></script>
<link href="/rich_text_editor/style.css" rel="stylesheet">
<script src="/rich_text_editor/index.js"></script>
<style>
#editor—wrapper {
border: 1px solid #ccc;
z-index: 100; /* 按需定义 */
}
#toolbar-container { border-bottom: 1px solid #ccc; }
#editor-container { height: 500px; }
</style>
</head>
<body>
<div class="layui-fluid">
<div class="layui-row" id="app_all">
<form action="" method="post" class="layui-form layui-form-pane">
<div class="layui-form-item">
<label for="title_v" class="layui-form-label">
<span class="x-red"></span>标题描述
</label>
<div class="layui-input-inline">
<input type="text" id="title_v" name="title_v" required="" lay-verify="title_v" autocomplete="off" class="layui-input" value="{$result.title}">
</div>
</div>
<div class="layui-form-item">
<label for="title_v" class="layui-form-label">
<span class="x-red"></span>上传封面
</label>
<div class="layui-input-inline">
<input type="file" id="upload_file_app" accept="image/*" lay-verify="upload_file_app" name="data_excel" class="layui-btn layui-btn-normal layui-btn-mini">
</div>
</div>
<div class="layui-form-item">
<label for="title_v" class="layui-form-label">
<span class="x-red"></span>预览
</label>
<div class="layui-input-inline">
<img id="preview_img" style="max-width:500px;" src="http://tc.pcxbc.com/{$result.cover_image}" alt="">
</div>
</div>
<div class="layui-form-item layui-form-text" style="max-width: 440px;">
<label class="layui-form-label">
发布板块
</label>
<table class="layui-table layui-input-block">
<tbody>
<tr>
<td>
{if condition="strpos($result.sector, '1') !== false && strpos($result.sector, '2') !== false && strpos($result.sector, '3') !== false"}
<input name="id[]" lay-skin="primary" type="checkbox" checked value="" title="全选" lay-filter="sector_all">
{else /}
<input name="id[]" lay-skin="primary" type="checkbox" value="" title="全选" lay-filter="sector_all">
{/if}
</td>
<td>
<div class="layui-input-block">
{if condition="strpos($result.sector, '1') !== false"}
<input name="id[]" lay-skin="primary" type="checkbox" checked value="1" title="推荐" lay-filter="sector_child">
{else /}
<input name="id[]" lay-skin="primary" type="checkbox" value="1" title="推荐" lay-filter="sector_child">
{/if}
{if condition="strpos($result.sector, '2') !== false"}
<input name="id[]" lay-skin="primary" type="checkbox" checked value="2" title="公告" lay-filter="sector_child">
{else /}
<input name="id[]" lay-skin="primary" type="checkbox" value="2" title="公告" lay-filter="sector_child">
{/if}
{if condition="strpos($result.sector, '3') !== false"}
<input name="id[]" lay-skin="primary" type="checkbox" checked value="3" title="圈" lay-filter="sector_child">
{else /}
<input name="id[]" lay-skin="primary" type="checkbox" value="3" title="圈" lay-filter="sector_child">
{/if}
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="layui-form-item layui-form-text" style="max-width: 440px;">
<label class="layui-form-label">
发布类型
</label>
<table class="layui-table layui-input-block">
<tbody>
<tr>
<td>
{if condition="strpos($result.type, '1') !== false && strpos($result.type, '2') !== false && strpos($result.type, '3') !== false && strpos($result.type, '4') !== false && strpos($result.type, '5') !== false"}
<input name="id[]" lay-skin="primary" type="checkbox" checked value="" title="全选" lay-filter="type_all">
{else /}
<input name="id[]" lay-skin="primary" type="checkbox" value="" title="全选" lay-filter="type_all">
{/if}
</td>
<td>
<div class="layui-input-block">
{if condition="strpos($result.type, '1') !== false"}
<input name="id[]" lay-skin="primary" type="checkbox" checked value="1" title="身高管理" lay-filter="type_child">
{else /}
<input name="id[]" lay-skin="primary" type="checkbox" value="1" title="身高管理" lay-filter="type_child">
{/if}
{if condition="strpos($result.type, '2') !== false"}
<input name="id[]" lay-skin="primary" type="checkbox" checked value="2" title="体重管理" lay-filter="type_child">
{else /}
<input name="id[]" lay-skin="primary" type="checkbox" value="2" title="体重管理" lay-filter="type_child">
{/if}
{if condition="strpos($result.type, '3') !== false"}
<input name="id[]" lay-skin="primary" type="checkbox" checked value="3" title="肺活训练" lay-filter="type_child">
{else /}
<input name="id[]" lay-skin="primary" type="checkbox" value="3" title="肺活训练" lay-filter="type_child">
{/if}
{if condition="strpos($result.type, '4') !== false"}
<input name="id[]" lay-skin="primary" type="checkbox" checked value="4" title="跳绳训练" lay-filter="type_child">
{else /}
<input name="id[]" lay-skin="primary" type="checkbox" value="4" title="跳绳训练" lay-filter="type_child">
{/if}
{if condition="strpos($result.type, '5') !== false"}
<input name="id[]" lay-skin="primary" type="checkbox" checked value="5" title="中考体测" lay-filter="type_child">
{else /}
<input name="id[]" lay-skin="primary" type="checkbox" value="5" title="中考体测" lay-filter="type_child">
{/if}
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="layui-form-item layui-form-text" style="max-width: 90%;">
<label for="desc" class="layui-form-label">
内容编辑
</label>
<div id="editor—wrapper">
<div id="toolbar-container"><!-- 工具栏 --></div>
<div id="editor-container"><!-- 编辑器 --></div>
</div>
</div>
<div class="layui-form-item">
<!-- <label for="L_repass" class="layui-form-label"></label> -->
<!-- <div class="layui-btn" id="add" lay-filter="add" lay-submit="">增加</div>
<input value="登录" lay-submit lay-filter="add" type="submit" class="layui-btn"> -->
<button class="layui-btn" lay-filter="add" lay-submit="">修改</button>
</div>
</form>
</div>
</div>
<script>
$('#upload_file_app').on('change', function() {
// 获取被选择的文件
var fileInput = $(this)[0];
var file = fileInput.files[0];
// 检查是否有文件被选择
if (file) {
var reader = new FileReader();
reader.onload = function(e) {
var img = document.getElementById('preview_img');
img.src = e.target.result; // 设置图片预览的src属性
img.style.display = 'block'; // 显示图片预览
};
reader.readAsDataURL(file); // 读取文件内容作为Data URL
}
});
</script>
<script>
var content_str = '{$result.content}';
// var content_str = '';
var html
const { createEditor, createToolbar } = window.wangEditor
const editorConfig = {
placeholder: 'Type here...',
onChange(editor) {
html = editor.getHtml()
html = html.replace(/\r?\n|\r/g, '');
// console.log('editor content', html)
// 也可以同步到 <textarea>
},
MENU_CONF: {}
}
editorConfig.MENU_CONF['uploadImage'] = {
server: '/editortext/upload_pic_action',
maxNumberOfFiles: 1,
maxFileSize: 10 * 1024 * 1024, // 10M
onError(file, err, res) {
// console.log(`${file.name} 上传出错`, err, res)
// console.log(file)
// console.log(err.message)
alert(err.message)
},
}
editorConfig.MENU_CONF['uploadVideo'] = {
server: '/editortext/upload_video_action',
maxFileSize: 100 * 1024 * 1024, // 100M
maxNumberOfFiles: 1,
onError(file, err, res) {
// console.log(`${file.name} 上传出错`, err, res)
// console.log(file)
// console.log(err.message)
alert(err.message)
},
}
const editor = createEditor({
selector: '#editor-container',
html: '<p><br></p>',
config: editorConfig,
mode: 'default', // or 'simple'
})
const toolbarConfig = {}
const toolbar = createToolbar({
editor,
selector: '#toolbar-container',
config: toolbarConfig,
mode: 'default', // or 'simple'
})
editor.setHtml(content_str)
</script>
<script>
var form
var id = '{$result.id}'
var sector_arr = '{$result.sector}'.split(",")
var type_arr = '{$result.type}'.split(",")
console.log(sector_arr)
var pd = true
layui.use(['form'], function () {
form = layui.form;
form.verify({
title_v: function(value) {
if (value == '') {
return '请先选择添加标题';
}
},
});
//监听提交
form.on('submit(add)',function(data) {
//发异步把数据提交给php
// console.log(html);
// console.log(sector_arr);
add_data()
return false;
});
form.on('checkbox(sector_all)', function(data){
if(data.elem.checked){
$(data.elem).parent().siblings('td').find('input').prop("checked", true);
form.render();
sector_arr = ['1','2','3','4','5'];
}else{
$(data.elem).parent().siblings('td').find('input').prop("checked", false);
form.render();
sector_arr = [];
}
console.log(sector_arr)
});
form.on('checkbox(sector_child)', function(data){
if(data.elem.checked){
$(data.elem).parent().siblings('td').find('input').prop("checked", true);
form.render();
sector_arr.push($(data.elem).val());
}else{
$(data.elem).parent().siblings('td').find('input').prop("checked", false);
form.render();
if (sector_arr.includes($(data.elem).val())) {
// 如果包含,则删除第一个匹配的元素
let index = sector_arr.indexOf($(data.elem).val());
if (index !== -1) {
sector_arr.splice(index, 1);
}
}
}
console.log(sector_arr)
});
form.on('checkbox(type_all)', function(data){
if(data.elem.checked){
$(data.elem).parent().siblings('td').find('input').prop("checked", true);
form.render();
type_arr = ['1','2','3','4','5'];
}else{
$(data.elem).parent().siblings('td').find('input').prop("checked", false);
form.render();
type_arr = [];
}
console.log(type_arr)
});
form.on('checkbox(type_child)', function(data){
if(data.elem.checked){
$(data.elem).parent().siblings('td').find('input').prop("checked", true);
form.render();
type_arr.push($(data.elem).val());
}else{
$(data.elem).parent().siblings('td').find('input').prop("checked", false);
form.render();
if (type_arr.includes($(data.elem).val())) {
// 如果包含,则删除第一个匹配的元素
let index = type_arr.indexOf($(data.elem).val());
if (index !== -1) {
type_arr.splice(index, 1);
}
}
}
console.log(type_arr)
});
});
// 功能性~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function add_data(){
if(pd === false){
return
}
var formdata = new FormData();
formdata.append('cover_image',$('#upload_file_app')[0].files[0])
formdata.append('id',id)
formdata.append('title',$("#title_v").val())
formdata.append('sector',sector_arr)
formdata.append('type',type_arr)
html = html.replace(/['"]/g, '\\$&');
formdata.append('content',html)
console.log(formdata)
load()
pd = false
$.ajax({
url:"/editortext/edit_content_action", //请求的url地址
contentType:false,
processData:false,
async:true,//请求是否异步默认为异步这也是ajax重要特性
data:formdata, //参数值
type:"POST", //请求方式
success:function(req){
c_load()
pd = true
console.log()
if(req.code == 0){
layer.alert("修改成功", {icon: 6},function() {
//关闭当前frame
xadmin.close();
// 可以对父窗口进行刷新
xadmin.father_reload();
});
}else{
layer.alert("修改失败"+req.msg, {icon: 6},function() {
//关闭当前frame
xadmin.close();
// 可以对父窗口进行刷新
xadmin.father_reload();
});
}
//请求成功时处理
console.log(req)
},
error:function(){
//请求出错处理
pd = true
}
});
}
//加载提示开启
function load() {
var index = layer.load(1, {
shade: [0.1, '#fff'] //0.1透明度的白色背景
});
}
// 关闭加载提示
function c_load() {
layer.close(layer.index)
}
</script>
</body>
</html>

View File

@ -0,0 +1,198 @@
<!DOCTYPE html>
<html class="x-admin-sm">
<head>
<meta charset="UTF-8">
<title>简要资讯列表</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />
<link rel="stylesheet" href="/x_admin/css/font.css">
<link rel="stylesheet" href="/x_admin/css/xadmin.css">
<script src="/x_admin/lib/layui/layui.js" charset="utf-8"></script>
<script type="text/javascript" src="/x_admin/js/xadmin.js"></script>
</head>
<body>
<div class="layui-fluid">
<div class="layui-row layui-col-space15">
<div class="layui-col-md12">
<div class="layui-card">
<div class="layui-card-body layui-table-body layui-table-main">
<table class="layui-table layui-form">
<thead>
<tr>
<th style="min-width: 30px;width:50px;">ID</th>
<th>标题</th>
<th style="min-width: 30px;width:115px;">类型</th>
<th>操作</th>
</tr>
</thead>
<tbody id='content'>
{volist name="result" id="vo"}
<tr>
<td>{$vo.id}</td>
<td>{$vo.title}</td>
<td>{$vo.type}</td>
<td class="td-status">
<button class="layui-btn" onclick="sendParamToParent('{$vo.id}')">选择</button>
</td>
</tr>
{/volist}
</tbody>
</table>
</div>
<div class="layui-card-body ">
<div id="page" style="text-align: center;">
</div>
</div>
</div>
</div>
</div>
</div>
</body>
<script>
function sendParamToParent(id) {
var param = id; // 这是要传递的参数
// 调用父窗口的一个函数,并传递参数
if (window.parent && window.parent.receiveParamFromIframe) {
window.parent.receiveParamFromIframe_information(param);
} else {
layer.msg('文章选择失败');
}
xadmin.close();
}
</script>
<script>
var form
layui.use(['laydate','form'], function(){
var laydate = layui.laydate;
form = layui.form;
//执行一个laydate实例
laydate.render({
elem: '#s_time' //指定元素
});
//执行一个laydate实例
laydate.render({
elem: '#e_time' //指定元素
});
});
var page_num;
var laypage;
var all_page = "{$num}";
layui.use('laypage', function () {
laypage = layui.laypage;
//执行一个laypage实例
laypage.render({
elem: 'page',
count: all_page, //数据总数,从服务端得到
limit: 10,
groups:10,
jump: function (obj, first) {
//首次不执行
if (!first) {
//obj包含了当前分页的所有参数比如
console.log(obj.curr); //得到当前页,以便向服务端请求对应页的数据。
console.log(obj.limit); //得到每页显示的条数
page_num = obj.curr;
jump_page(page_num)
}
}
});
});
function find(pd) {
if(!page_num || pd == 'y'){
page_num = 1;
}
page({
"page_num":page_num,
"tt":1},pd);
}
function page(data,pd) {
console.log(data)
load()
$.ajax({
url: "index", //请求的url地址s
dataType: "json", //返回格式为json
async: true,//请求是否异步默认为异步这也是ajax重要特性
data: data, //参数值
type: "POST", //请求方式
success: function (req) {
console.log(req)
c_load();
if (req['code'] == 0) {
var str,str_s,str_c,str_all="";
for (let i = 0; i < req['data']['data'].length; i++) {
if(req['data']['data'][i]['is_del'] == 1){
str = '<span onclick="app_stop(this,\''+ req['data']['data'][i]['id'] +'\')" class="layui-btn layui-btn-normal layui-btn-mini layui-btn-disabled" title="停用">已停用</span>'
}else{
str = '<span onclick="app_stop(this,\''+ req['data']['data'][i]['id'] +'\')" class="layui-btn layui-btn-normal layui-btn-mini" title="启用">已启用</span>'
}
str_c = "<tr>"+
"<td>"+ req['data']['data'][i]['id'] +"</td>"+
"<td>"+ req['data']['data'][i]['title'] +"</td>"+
"<td>"+ req['data']['data'][i]['create_time'] +"</td>"+
"<td>"+ req['data']['data'][i]['update_time'] +"</td>"+
'<td><input type="text" class="layui-input x-sort top_up_edit" name="order_edit" value="'+ req['data']['data'][i]['top_up'] +'" onblur="edit_order_action(this,\''+ req['data']['data'][i]['top_up'] +'\',\'top\',\''+ req['data']['data'][i]['id'] +'\')"></td>'+
'<td><input type="text" class="layui-input x-sort loop_img_edit" name="order_edit" value="'+ req['data']['data'][i]['loop_img'] +'" onblur="edit_order_action(this,\''+ req['data']['data'][i]['loop_img'] +'\',\'loop\',\''+ req['data']['data'][i]['id'] +'\')"></td>'+
'<td class="td-status">'+
'<button class="layui-btn" onclick="xadmin.open(\'查看\',\'/editortext/edit_content?id='+ req['data']['data'][i]['id'] +'\',\'100%\',\'100%\')">查看</button>'+
str+
'</td></tr>'
str_all = str_all+str_c;
}
$('#content').html(str_all);
form.render();
if(pd == 'y'){
$("#page").html("")
laypage.render({
elem: 'page',
count: req['data']['num'], //数据总数,从服务端得到
limit: 10,
groups:10,
jump: function (obj, first) {
//首次不执行
if (!first) {
//obj包含了当前分页的所有参数比如
console.log(obj.curr); //得到当前页,以便向服务端请求对应页的数据。
console.log(obj.limit); //得到每页显示的条数
page_num = obj.curr;
// page({"page":page_num,"tt":1});
find("n")
}
}
});
}
} else {
layer.msg(req['msg'])
}
},
error: function () {
//请求出错处理
}
});
}
//加载提示开启
function load() {
var index = layer.load(1, {
shade: [0.1, '#fff'] //0.1透明度的白色背景
});
}
// 关闭加载提示
function c_load() {
layer.close(layer.index)
}
</script>
</html>

View File

@ -0,0 +1,294 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{$result.title}</title>
<script src="/x_admin/js/jq.js"></script>
<script type="text/javascript" src="/x_admin/lib/layui/layui.js" charset="utf-8"></script>
<script type="text/javascript" src="/x_admin/js/xadmin.js"></script>
<style>
*{
margin: 0 0;
padding: 0 0;
}
/* body{
display: flex;
flex-direction: column;
flex-wrap: nowrap;
align-items: center;
} */
#big_box{
width: 90vw;
position: absolute;
top: 0;
left:0;
right: 0;
margin: 0 auto;
display: flex;
flex-direction: column;
justify-content: center;
/* background-color: red; */
}
.content{
width: 100%;
}
p{
margin: 2vw 0;
}
img{
max-width: 100%;
display: block;
}
video{
max-width: 100%;
}
.action_region{
width: 100%;
margin-bottom: 15vw;
display: flex;
justify-content: flex-end;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
}
.action_region span{
font-size: 6vw;
}
#is_like{
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: center;
align-items: center;
}
#reading{
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: center;
align-items: center;
}
.heart_full, .heart_empty {
cursor: pointer;
transition: all 0.3s ease;
position: relative;
display: inline-block;
width: 7vw; /* 心形的宽度 */
height: 7vw; /* 心形的高度 */
cursor: pointer;
}
.heart_full::before {
position: absolute;
content: "";
top: 0;
left: 0;
width: 100%;
height: 100%;
background-repeat: no-repeat;
background-position: center;
background-size: contain;
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="%23FF0000" d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/></svg>');
}
.heart_empty::before {
position: absolute;
content: "";
top: 0;
left: 0;
width: 100%;
height: 100%;
background-repeat: no-repeat;
background-position: center;
background-size: contain;
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="%23888888" d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/></svg>');
}
.reading {
position: relative;
display: inline-block;
width: 7vw; /* 书籍的宽度 */
height: 7vw; /* 书籍的高度 */
cursor: pointer;
}
.reading::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-repeat: no-repeat;
background-position: center;
background-size: contain;
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="%23FFA500" d="M18 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 18H6V4h12v16zM8 10h4v2H8v-2zm0 4h4v2H8v-2z"/></svg>');
}
table {
border-collapse: collapse; /* 这将合并表格边框,使得单元格之间没有间距 */
}
th{
background-color: #f5f2f0;
border: 1px solid #ccc;
text-align: center;
}
td{
border: 1px solid #ccc;
}
/* 外部容器的样式 */
.table-container {
max-width: 90vw; /* 最大宽度为视口宽度的80% */
overflow-x: auto; /* 水平方向溢出时显示滚动条 */
margin: 0 auto; /* 可选:让容器水平居中 */
}
</style>
</head>
<body>
<div id="big_box">
<div class="content">{$result.content}</div>
<div class="action_region">
<div id="is_like">
<div id="is_like_a" class=""></div>
<span class="is_like_num">{$result.i_like}</span>
</div>
<div id="reading">
<div class="reading"></div>
<span class="reading_num">{$result.reading}</span>
</div>
</div>
</div>
</body>
</html>
<script>
var user_like = "{$result.user_like}";
var i_like_num = parseInt("{$result.i_like}");
// 根据 user_like 的值设置初始类
var isLikeElement = document.getElementById('is_like_a');
if (user_like == 1) {
isLikeElement.classList.add('heart_full');
} else {
isLikeElement.classList.add('heart_empty');
}
document.getElementById('is_like_a').addEventListener('click', function() {
load()
if(user_like == 3){
c_load()
alert('请登录');
}else{
user_like_do()
}
});
function user_like_do(){
$.ajax({
url:"/testedition/user_like_it", //请求的url地址
dataType:"json", //返回格式为json
async:true,//请求是否异步默认为异步这也是ajax重要特性
data:{"id":"{$result.id}",'token':"{$result.token}"}, //参数值
type:"POST", //请求方式
success:function(req){
c_load()
//请求成功时处理
if(req.code == 0){
if(req.data.user_like == 1){
i_like_num = i_like_num + 1;
isLikeElement.classList.remove('heart_empty');
isLikeElement.classList.add('heart_full');
document.querySelector('.is_like_num').innerHTML = i_like_num;
}else if(req.data.user_like == 0){
i_like_num = i_like_num - 1;
isLikeElement.classList.remove('heart_full');
isLikeElement.classList.add('heart_empty');
document.querySelector('.is_like_num').innerHTML = i_like_num;
}
}
},
error:function(){
//请求出错处理
}
});
}
//加载提示开启
function load() {
var index = layer.load(1, {
shade: [0.1, '#fff'] //0.1透明度的白色背景
});
}
// 关闭加载提示
function c_load() {
layer.close(layer.index)
}
</script>
<script>
// 获取页面上所有的 video 元素
const videos = document.querySelectorAll('video');
let hasScrolled = false;
// 监听滑动事件
document.addEventListener('touchstart', handleScroll, { passive: true });
function handleScroll() {
if (!hasScrolled) {
hasScrolled = true;
playFirstFrameAndPause(videos);
// 移除滑动事件监听器,避免多次触发
document.removeEventListener('touchstart', handleScroll);
}
}
function playFirstFrameAndPause(videos) {
videos.forEach(video => {
video.currentTime = 0; // 设置当前时间为 0 秒
video.play().then(() => {
video.pause(); // 立即暂停,显示第一帧
}).catch(error => {
console.error('Error playing video:', error);
});
});
}
</script>
<script>
window.onload = function() {
var content_data = '{$result.content}'
document.querySelector('div.content').innerHTML = content_data.replace(/\\/g, '');
// 获取页面上的所有表格
var tables = document.getElementsByTagName('table');
// 遍历每个表格
for (var i = 0; i < tables.length; i++) {
var table = tables[i];
// 创建一个div容器
var container = document.createElement('div');
container.className = 'table-container'; // 应用CSS样式
// 将表格移动到容器中
table.parentNode.insertBefore(container, table);
container.appendChild(table);
// 强制浏览器重新计算布局,以便我们可以获取正确的宽度
// 注意:这种方法可能不是最高效的,但在这种简单场景下通常足够
var style = window.getComputedStyle(table);
var tableWidth = parseFloat(style.width.replace('px', ''));
var viewportWidth = window.innerWidth || document.documentElement.clientWidth;
var maxWidth = viewportWidth * 0.8; // 计算80vw的值
// 如果表格宽度超过了80vw则不需要额外操作因为容器已经设置了max-width
// 但为了演示,我们可以检查并打印出信息
if (tableWidth > maxWidth) {
console.log('Table ' + (i + 1) + ' is wider than 80vw and is wrapped in a container.');
} else {
// 实际上,如果表格没有超过宽度,你可能想要移除容器或做一些其他处理
// 但在这个例子中我们保留容器因为max-width会确保它不会溢出
console.log('Table ' + (i + 1) + ' fits within 80vw, but is still wrapped in a container for demonstration.');
}
// 注意由于我们设置了容器的max-width为80vw并且overflow-x为auto
// 所以即使表格宽度超过容器的宽度滚动条也会自动出现无需额外JS处理。
}
};
</script>

View File

@ -2,7 +2,7 @@
<html class="x-admin-sm">
<head>
<meta charset="UTF-8">
<title>所有卡片管理</title>
<title>弹窗图管理</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />
@ -58,43 +58,37 @@
</form>
</div> -->
<div class="layui-card-header">
<button class="layui-btn layui-btn-danger" onclick="delAll()"><i class="layui-icon"></i>批量停用</button>
<!-- <button class="layui-btn layui-btn-danger" onclick="delAll()"><i class="layui-icon"></i>批量停用</button> -->
<!-- <button class="layui-btn" onclick="xadmin.open('添加用户','/appversion/app_add','100%','100%')"><i class="layui-icon"></i>添加</button> -->
<button class="layui-btn" onclick="xadmin.open('添加版本','/card/card_add','80%','60%')"><i class="layui-icon"></i>添加</button>
<button class="layui-btn" onclick="xadmin.open('添加banner','/notice/banner_add','80%','80%')"><i class="layui-icon"></i>添加</button>
</div>
<div class="layui-card-body layui-table-body layui-table-main">
<table class="layui-table layui-form">
<thead>
<tr>
<th><input type="checkbox" lay-filter="checkall" name="" lay-skin="primary"></th>
<th>ID</th>
<th>卡片名称</th>
<th>卡片图标</th>
<th>卡片描述</th>
<th>创建时间</th>
<th>状态</th>
<th>操作</th></tr>
<th style="min-width: 30px;width:50px;">ID</th>
<th>标题</th>
<th style="min-width: 30px;width:115px;">创建时间</th>
<th>封面预览</th>
<th style="min-width: 30px;width:50px;">轮播排序</th>
<th>操作</th>
</tr>
</thead>
<tbody id='content'>
{volist name="result" id="vo"}
<tr>
<td><input type="checkbox" name="id" value="{$vo.id}" lay-skin="primary"></td>
<td>{$vo.id}</td>
<td>{$vo.name}</td>
<td><img src="{$vo.pic}" alt=""></td>
<td>{$vo.content}</td>
<td>{$vo.title}</td>
<td>{$vo.create_time}</td>
<td><img src="{$vo.pic}" alt=""></td>
<td><input type="text" class="layui-input x-sort loop_img_edit" name="order_edit" value="{$vo.sort_num}" onblur="edit_order_action(this,'{$vo.sort_num}','{$vo.id}')"></td>
<td class="td-status">
<button class="layui-btn" onclick="xadmin.open('查看','/notice/banner_edit?id={$vo.id}','80%','80%')">查看</button>
{if condition="$vo.is_del == 1"}
<span onclick="app_stop(this,'{$vo.id}')" class="layui-btn layui-btn-normal layui-btn-mini layui-btn-disabled" title="停用">已停用</span>
{else /}
<span onclick="app_stop(this,'{$vo.id}')" class="layui-btn layui-btn-normal layui-btn-mini" title="启用">已启用</span>
{/if}
</td>
<td>
<button class="layui-btn" onclick="xadmin.open('修改','/card/card_edit?id={$vo.id}','80%','60%')">修改</button>
</td>
</tr>
{/volist}
@ -105,18 +99,6 @@
<div id="page" style="text-align: center;">
</div>
</div>
<!-- <div class="layui-card-body ">
<div class="page">
<div>
<a class="prev" href="">&lt;&lt;</a>
<a class="num" href="">1</a>
<span class="current">2</span>
<a class="num" href="">3</a>
<a class="num" href="">489</a>
<a class="next" href="">&gt;&gt;</a>
</div>
</div>
</div> -->
</div>
</div>
</div>
@ -127,18 +109,6 @@
layui.use(['laydate','form'], function(){
var laydate = layui.laydate;
form = layui.form;
// 监听全选
form.on('checkbox(checkall)', function(data){
if(data.elem.checked){
$('tbody input').prop('checked',true);
}else{
$('tbody input').prop('checked',false);
}
form.render('checkbox');
});
//执行一个laydate实例
laydate.render({
@ -149,9 +119,9 @@
laydate.render({
elem: '#e_time' //指定元素
});
});
var page_num;
var laypage;
var all_page = "{$num}";
@ -177,6 +147,35 @@
});
});
function edit_order_action(e,data,id){
if($(e).val() == data){
return
}
load()
$.ajax({
url:"/notice/pop_update_sort", //请求的url地址
dataType:"json", //返回格式为json
async:true,//请求是否异步默认为异步这也是ajax重要特性
data:{
"id":id,
'data':$(e).val(),
}, //参数值
type:"POST", //请求方式
success:function(req){
c_load()
//请求成功时处理
if(req['code'] == 0){
layer.msg('操作成功!',{icon: 6});
}else{
layer.msg('操作失败!',{icon: 5});
}
},
error:function(){
//请求出错处理
}});
}
/*用户-停用*/
function app_stop(obj,id){
@ -191,14 +190,13 @@
is_del = 0
num = 6
}
// console.log('点击时'+$(obj).attr('title')+'====='+id+'===传到后台是否删除:'+is_del)
layer.confirm('确认要'+ title +'吗?',function(index){
load()
$.ajax({
url:"/card/card_del", //请求的url地址
url:"/notice/pop_stop_run", //请求的url地址
dataType:"json", //返回格式为json
async:true,//请求是否异步默认为异步这也是ajax重要特性
data:{"id":id,'is_del':is_del}, //参数值
data:{"id":id,'data':is_del}, //参数值
type:"POST", //请求方式
success:function(req){
c_load()
@ -222,45 +220,6 @@
});
}
function delAll (argument) {
// layer.msg('停用成功', {icon: 2});
// return
var ids = [];
// 获取选中的id
$('tbody input').each(function(index, el) {
if($(this).prop('checked')){
ids.push($(this).val())
}
});
if(ids.length <= 0){
return
}
console.log(ids);
layer.confirm('确认要停用吗ID为'+ids.toString(),function(index){
//捉到所有被选中的,发异步进行删除
$.ajax({
url:"/card/card_del", //请求的url地址
dataType:"json", //返回格式为json
async:true,//请求是否异步默认为异步这也是ajax重要特性
data:{"id":ids,'is_del':1}, //参数值
type:"POST", //请求方式
success:function(req){
c_load()
//请求成功时处理
if(req['code'] == 0){
//发异步把用户状态进行更改
layer.msg('停用成功', {icon: 1});
$(".layui-form-checked").not('.header').parents('tr').find(".td-status").find('span').addClass('layui-btn-disabled').html('已停用');
}else{
layer.msg('操作失败!',{icon: 2});
}
},
error:function(){
//请求出错处理
}});
});
}
function find(pd) {
if(!page_num || pd == 'y'){
@ -268,11 +227,6 @@
}
page({
"status_num":$('#status_num').val(),
"tel":$('#tel').val(),
"email":$('#email').val(),
"s_time":$('#s_time').val(),
"e_time":$('#e_time').val(),
"page_num":page_num,
"tt":1},pd);
}
@ -280,7 +234,7 @@
console.log(data)
load()
$.ajax({
url: "member_list", //请求的url地址s
url: "index", //请求的url地址s
dataType: "json", //返回格式为json
async: true,//请求是否异步默认为异步这也是ajax重要特性
data: data, //参数值
@ -294,21 +248,21 @@
for (let i = 0; i < req['data']['data'].length; i++) {
if(req['data']['data'][i]['is_del'] == 1){
str = '<span onclick="member_stop(this,\''+req['data']['data'][i]['id']+'\')" class="layui-btn layui-btn-normal layui-btn-mini layui-btn-disabled" title="停用">已停用</span>'
str = '<span onclick="app_stop(this,\''+ req['data']['data'][i]['id'] +'\')" class="layui-btn layui-btn-normal layui-btn-mini layui-btn-disabled" title="停用">已停用</span>'
}else{
str = '<span onclick="member_stop(this,\''+ req['data']['data'][i]['id'] +'\')" class="layui-btn layui-btn-normal layui-btn-mini" title="启用">已启用</span>'
str = '<span onclick="app_stop(this,\''+ req['data']['data'][i]['id'] +'\')" class="layui-btn layui-btn-normal layui-btn-mini" title="启用">已启用</span>'
}
str_c = "<tr>"+
'<td><input type="checkbox" name="id" value="'+req['data']['data'][i]['id']+'" lay-skin="primary"></td>'+
'<td>'+req['data']['data'][i]['id']+'</td>'+
'<td>'+req['data']['data'][i]['token']+'</td>'+
'<td>'+req['data']['data'][i]['tel']+'</td>'+
'<td>'+req['data']['data'][i]['email']+'</td>'+
'<td>'+req['data']['data'][i]['create_time']+'</td>'+
"<td>"+ req['data']['data'][i]['id'] +"</td>"+
"<td>"+ req['data']['data'][i]['title'] +"</td>"+
"<td>"+ req['data']['data'][i]['create_time'] +"</td>"+
"<td>"+ req['data']['data'][i]['update_time'] +"</td>"+
'<td><input type="text" class="layui-input x-sort top_up_edit" name="order_edit" value="'+ req['data']['data'][i]['top_up'] +'" onblur="edit_order_action(this,\''+ req['data']['data'][i]['top_up'] +'\',\'top\',\''+ req['data']['data'][i]['id'] +'\')"></td>'+
'<td><input type="text" class="layui-input x-sort loop_img_edit" name="order_edit" value="'+ req['data']['data'][i]['loop_img'] +'" onblur="edit_order_action(this,\''+ req['data']['data'][i]['loop_img'] +'\',\'loop\',\''+ req['data']['data'][i]['id'] +'\')"></td>'+
'<td class="td-status">'+
str+
'</td>'
'</tr>'
'<button class="layui-btn" onclick="xadmin.open(\'查看\',\'/editortext/edit_content?id='+ req['data']['data'][i]['id'] +'\',\'100%\',\'100%\')">查看</button>'+
str+
'</td></tr>'
str_all = str_all+str_c;
}
$('#content').html(str_all);

View File

@ -144,21 +144,24 @@
<i class="iconfont">&#xe6a7;</i>
<cite>操作管理</cite></a>
</li>
<!-- <li>
<a onclick="xadmin.add_tab('首页弹窗管理','/notice/pop_index')">
<i class="iconfont">&#xe6a7;</i>
<cite>首页弹窗管理</cite></a>
</li>
<li>
<a onclick="xadmin.add_tab('公告管理','/notice/notice_index')">
<i class="iconfont">&#xe6a7;</i>
<cite>公告管理</cite></a>
</li> -->
</ul>
</li>
<li>
<a href="javascript:;">
<i class="iconfont left-nav-li" lay-tips="城市联动">&#xe723;</i>
<i class="iconfont left-nav-li" lay-tips="商业合作">&#xe723;</i>
<cite>商业合作</cite>
<i class="iconfont nav_right">&#xe697;</i></a>
<ul class="sub-menu">
<li>
<a onclick="xadmin.add_tab('操作管理','/business/business_index')">
<i class="iconfont">&#xe6a7;</i>
<cite>操作管理</cite></a>
</li>
</ul>
</li>
<!-- <li>
<a href="javascript:;">
<i class="iconfont left-nav-li" lay-tips="技术支持管理">&#xe723;</i>
<cite>技术支持管理</cite>
<i class="iconfont nav_right">&#xe697;</i></a>
<ul class="sub-menu">
@ -168,7 +171,7 @@
<cite>技术支持列表</cite></a>
</li>
</ul>
</li>
</li> -->
<!-- <li>
<a href="javascript:;">
<i class="iconfont left-nav-li" lay-tips="管理员管理">&#xe726;</i>

View File

@ -21,6 +21,7 @@
<label for="title_v" class="layui-form-label">
<span class="x-red"></span>标题描述
</label>
<div class="layui-input-inline" style="width: 80%;">
<input type="text" id="title_v" name="title_v" lay-verify="title_v" autocomplete="off" class="layui-input">
</div>
@ -91,6 +92,7 @@
</div>
</div>
<script>
var ts = true
var pic_data = []
function receiveParamFromIframe(param) {
pic_data = param
@ -113,6 +115,14 @@
$('#parameter_data').blur()
}else if($('#data_type').val() == 2){
layer.msg('请填写微信小程序APPID')
$('#jump_url').attr('placeholder', '填写页面路径前请先确认已经配置小程序的URL Scheme');
if(ts){
layer.alert(
"您选择了小程序类型填写页面路径前请先确认已经配置小程序的URL Scheme。小程序后台->账号设置->隐私与安全->明文scheme拉起此小程序->配置->在“小程序 path”中添加页面路径多个路径以回车换行的方式书写",
{icon: 6}
);
ts = false;
}
}else{
layer.msg('请选择跳转类型')
}
@ -150,7 +160,9 @@
},
jump_url: function(value) {
if ($('#data_type').val() == 2) {
return '请先填写微信小程序页面路径';
if($('#jump_url').val() == ''){
return '请先填写微信小程序页面路径';
}
}
},

View File

@ -119,6 +119,7 @@
</div>
</div>
<script>
var ts = true
var data_id = "{$result.id}"
var pic_data = []
function receiveParamFromIframe(param) {
@ -142,6 +143,13 @@
$('#parameter_data').blur()
}else if($('#data_type').val() == 2){
layer.msg('请填写微信小程序APPID')
if(ts){
layer.alert(
"您选择了小程序类型填写页面路径前请先确认已经配置小程序的URL Scheme。小程序后台->账号设置->隐私与安全->明文scheme拉起此小程序->配置->在“小程序 path”中添加页面路径多个路径以回车换行的方式书写",
{icon: 6}
);
ts = false;
}
}else{
layer.msg('请选择跳转类型')
}
@ -179,7 +187,9 @@
},
jump_url: function(value) {
if ($('#data_type').val() == 2) {
return '请先填写微信小程序页面路径';
if($('#jump_url').val() == ''){
return '请先填写微信小程序页面路径';
}
}
},

View File

@ -2,7 +2,7 @@
<html class="x-admin-sm">
<head>
<meta charset="UTF-8">
<title>banner图管理</title>
<title>操作管理</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />

View File

@ -614,7 +614,11 @@ class Base extends Controller{
// 处理身高体重的单位转换它们为cm和kg。
function convertHeightAndWeight($height, $weight) {
public function convertHeightAndWeight($height, $weight) {
// 加 bcadd(,,20)
// 减 bcsub(,,20)
// 乘 bcmul(,,20)
// 除 bcdiv(,,20)
// 定义单位转换比例
$heightConversion = [
'cm' => 1,
@ -635,8 +639,17 @@ class Base extends Controller{
];
// 处理 height
if (preg_match('/([\d.]+)(cm|inch|ft-in)/', $height, $matches)) {
$heightValue = floatval($matches[1]);
// $heightValue = floatval($matches[1]);
$heightValue = $matches[1];
$heightUnit = $matches[2];
if($heightUnit == 'ft-in'){
// 如果单位为st:lb但是数据格式不对
$heightValue = str_replace($heightUnit, "", $height);
if(count(explode('-', $heightValue)) < 2){
$heightValue = str_replace("-", "", $heightValue);
$heightValue = $heightValue."-0";
}
}
if (isset($heightConversion[$heightUnit])) {
if (is_callable($heightConversion[$heightUnit])) {
$heightInCm = $heightConversion[$heightUnit]($heightValue);
@ -656,10 +669,19 @@ class Base extends Controller{
}
}
// 处理 weight
if (preg_match('/([\d.]+)(kg|斤|st:lb|lb)/', $weight, $matches)) {
$weightValue = floatval($matches[1]);
if (preg_match('/([\d.:]+)(kg|斤|st:lb|lb)/', $weight, $matches)) {
$weightValue = $matches[1];
$weightUnit = $matches[2];
if($weightUnit == 'st:lb'){
// 如果单位为st:lb但是数据格式不对
$weightValue = str_replace($weightUnit, "", $weight);
if(count(explode(':', $weightValue)) < 2){
$weightValue = str_replace(":", "", $weightValue);
$weightValue = $weightValue.":0";
}
}
if (isset($weightConversion[$weightUnit])) {
if (is_callable($weightConversion[$weightUnit])) {
$weightInKg = $weightConversion[$weightUnit]($weightValue);
@ -678,10 +700,10 @@ class Base extends Controller{
$weightInKg = false;
}
}
return [
'height_in_cm' => $heightInCm,
'weight_in_kg' => $weightInKg
'height_in_cm' => bcmul($heightInCm,1,2),
'weight_in_kg' => bcmul($weightInKg,1,2)
];
}

View File

@ -31,6 +31,28 @@ class Download extends Base{
return $this->fetch();
}
public function business_cooperation(){
return $this->fetch();
}
public function business_cooperation_action(){
$data = input();
$result = Db::table('admin_business_cooperation_log')->insert([
'name'=>$data['name'],
'tel'=>$data['phone'],
'company'=>$data['company'],
'intention_data'=>implode(',',$data['selectedValues']),
'notes_data'=>$data['remark'],
'create_time'=>date('Y-m-d H:i:s'),
]);
if($result){
$this->send_email_api_error(["tsf3920322@126.com"],['title'=>'商户合作','from_user_name'=>'reedaw商务','content'=>'有一封商户合作']);
return json(['code'=>0,'msg'=>'提交成功']);
}else{
return json(['code'=>10001,'msg'=>'网络错误,请直接联系商务合作电话/微信13590959084']);
}
}
public function ceshi(){
$data = input();
$url = 'https://klcz.pcxbc.com/open-api/calc/healthcalc/bodyfat3';

View File

@ -25,9 +25,7 @@ class Msginformation extends Base{
// 获取板块,及板块下类型标签
public function get_sector_label_msg($data = ['token'=>'6441bf7dabea7b3360a30240d3b19fc5']){
try {
if(count(input('post.')) > 0){
$data = input('post.');
}
$data = input('post.');
if(!array_key_exists('token', $data)){
return $this->msg(10001);
}
@ -72,6 +70,10 @@ class Msginformation extends Base{
}
if(!$this->verify_data_is_ok($data['page'],'intnum')){
return $this->msg(10005);
}else{
if($data['page'] < 1){
return $this->msg(10005,'页码不能小于1');
}
}
$return_data = $this->get_sector_content_msg_action($data);
@ -214,6 +216,38 @@ class Msginformation extends Base{
return $this->msg(99999);
}
}
// 给微信使用的中间页(拉起微信)
// public function open_wechat_content($data=['id'=>8]){
public function open_wechat_content(){
try {
$data = input();
if(!array_key_exists('id', $data)){
$this->record_api_log($data, null, ['code'=>10001,'msg'=>'',[]]);
return $this->msg(10001);
}
$url = Db::table('admin_notice_banner')->where(['id'=>$data['id']])->field('type,jump_url')->find();
if(!$url['type'] || $url['type'] != 2){
echo '<div style="font-size: 30px;font-weight: bold;">页面跑丢了... =。=</div>';
die;
}
header('Location: '.$url['jump_url']);
} 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'] .= "行号: " . $e->getLine() . "\n";
$logContent['all_content'] .= "跟踪信息:\n" . $e->getTraceAsString() . "\n";
$this->record_api_log($data, $logContent, null);
return $this->msg(99999);
}
}
################################################################业务################################################################
################################################################get_sector_label_msg
public function get_sector_label_msg_action($data){
@ -232,8 +266,6 @@ class Msginformation extends Base{
]
],
];
// 获取需要版块id start
$sector = Db::query("
SELECT
@ -266,12 +298,14 @@ class Msginformation extends Base{
");
if(count($loop_result) > 0){
foreach ($loop_result as $k => $v) {
$loop_result[$key]['jump_url'] = "https://tc.pcxbc.com/editortext/model_content?id=".$v['id']."&token=".$data['token'];
// $loop_result[$key]['jump_url'] = "https://tc.pcxbc.com/editortext/model_content?id=".$v['id']."&token=".$data['token'];
$loop_result[$key]['jump_url'] = "https://tc.pcxbc.com/editortext/model_content";
}
}
$Template_arr[$value]['loop_data'] = $loop_result;
array_push($return_data, $Template_arr[$value]);
}
// 填充进去版块的轮播end
return $this->msg($return_data);
}
@ -308,7 +342,8 @@ class Msginformation extends Base{
");
if(count($content_result) > 0){
foreach ($content_result as $key => $value) {
$content_result[$key]['jump_url'] = "https://tc.pcxbc.com/editortext/model_content?id=".$value['id']."&token=".$data['token'];
// $content_result[$key]['jump_url'] = "https://tc.pcxbc.com/editortext/model_content?id=".$value['id']."&token=".$data['token'];
$content_result[$key]['jump_url'] = "https://tc.pcxbc.com/editortext/model_content";
}
}
$return_result['content_data'] = $content_result;
@ -391,8 +426,9 @@ class Msginformation extends Base{
'notice'=>[],
'banner'=>[]
];
// 所有可用记录
$all_data = Db::table($this->msginformation_use_db_name['3'])->where(['is_del'=>0])->select();
// return $this->msg($return_data);
// 所有可用记录.
$all_data = Db::table($this->msginformation_use_db_name['3'])->where("is_del = 0 AND scene_data IN (1,2,3)")->select();
// 用户阅读记录
$user_read_log = Db::table($this->msginformation_use_db_name['2'])->where(['token'=>$data['token']])->field('aetc_id')->select();
$user_read_data = [];
@ -407,12 +443,14 @@ class Msginformation extends Base{
if($value['scene_data'] != 3){
unset($all_data[$key]);
}else{
$all_data[$key]['jump_url'] = $all_data[$key]['jump_url']."&token=".$data['token'];
// $all_data[$key]['jump_url'] = $all_data[$key]['jump_url']."&token=".$data['token'];
$all_data[$key]['jump_url'] = $all_data[$key]['jump_url'];
$all_data[$key]['type'] = 'h5';
$all_data[$key]['id'] = $value['parameter_data'];
}
}else{
$all_data[$key]['jump_url'] = $all_data[$key]['jump_url']."&token=".$data['token'];
// $all_data[$key]['jump_url'] = $all_data[$key]['jump_url']."&token=".$data['token'];
$all_data[$key]['jump_url'] = $all_data[$key]['jump_url'];
$all_data[$key]['type'] = 'h5';
$all_data[$key]['id'] = $value['parameter_data'];
}
@ -430,6 +468,9 @@ class Msginformation extends Base{
$all_data[$key]['appid'] = $appid;
$all_data[$key]['path'] = $path;
// 重新定义跳转链接为中间页
$all_data[$key]['jump_url'] = "https://tc.pcxbc.com/open_wechat_content";
}
// $all_data[$key]['id'] = $all_data[$key]['parameter_data'];
unset($all_data[$key]['parameter_data']);

View File

@ -47,7 +47,11 @@ class Skip extends Base{
if(!$this->verify_data_is_ok($data['type'],'str')){
return $this->msg(10005);
}
if(!$this->isValidInteger($data['num']+0) || !$this->isValidInteger($data['time_m']+0) || !$this->isValidInteger($data['time_s']+0)){
// {"aud_id":"331","num":"100","r_time":"2025-01-15","time_m":"","time_s":"","type":"free","token":"2581d40766e7cfd25ca140f3514072bd","aan_id":"254"}
// if(!$this->isValidInteger($data['num']+0) || !$this->isValidInteger($data['time_m']+0) || !$this->isValidInteger($data['time_s']+0)){
// $return_data = $this->msg(10005,'跳绳数量或者分钟、秒钟值必须为整数');
// }
if(!$this->verify_data_is_ok($data['num'],'intnum') || !$this->verify_data_is_ok($data['time_m'],'intnum') || !$this->verify_data_is_ok($data['time_s'],'intnum')){
$return_data = $this->msg(10005,'跳绳数量或者分钟、秒钟值必须为整数');
}
if($data['num'] <= 0){

View File

@ -0,0 +1,398 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, initial-scale=1,minimum-scale=1, maximum-scale=1,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta http-equiv="Access-Control-Allow-Origin" content="*">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="format-detection" content="telephone=no, email=no">
<meta name="full-screen" content="true">
<meta name="screen-orientation" content="portrait">
<meta name="x5-fullscreen" content="true">
<meta name="360-fullscreen" content="true">
<title>商务合作</title>
<script src="/x_admin/js/jq.js"></script>
<script type="text/javascript" src="/x_admin/lib/layui/layui.js" charset="utf-8"></script>
<script type="text/javascript" src="/x_admin/js/xadmin.js"></script>
<style>
*{
padding: 0 0;
margin: 0 0;
}
.big_box{
width: 100vw;
min-height: 100vh;
position: absolute;
top: 0;
left: 0;
background: url(/tsf/business_bg.jpg) no-repeat;
background-size: 100% 100%;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
align-items: center;
}
.content{
width: 85vw;
max-width: 880px;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
border-radius: 1vw;
background-color: white;
margin: 24px 0;
overflow: hidden;
align-items: center;
}
.content img{
width: 100%;
height: auto;
}
.content_c{
width: 100%;
padding: 2% 12%;
box-sizing: border-box;
}
.title_t{
border: none;
text-align: center;
color: rgba(8, 14, 23, 0.9);
font-weight: 600;
font-size: 28px;
line-height: 40px;
word-break: break-all;
white-space: pre-wrap;
overflow: visible;
margin: 4% 0;
}
.title_c2{
font-size: 12px;
margin-bottom: 10%;
}
.title_c2 span{
color: rgb(17, 106, 240);
}
.write_box{
width: 100%;
font-size: 16px;
margin: 10% 0;
}
.write_box_t{
font-weight: 600;
}
.write_box_r{
color: red;
}
.write_k{
padding: 8px 12px;
position: relative;
border-radius: 6px;
border: 1px solid rgba(8, 14, 23, 0.24);
display: flex;
outline: 0 !important;
word-break: break-all;
margin: 2% 0;
}
.write_k textarea{
width: 100%;
resize: none;
text-overflow: ellipsis;
line-height: 22px;
border: none !important;
border-radius: 0;
background: transparent !important;
box-shadow: none !important;
outline: 0 !important;
cursor: auto;
padding: 0;
min-height: 22px;
margin: 0 1%;
}
.ksapc-select-write {
width: 100%;
}
.ksapc-select-write-tip {
margin-bottom: 10px;
font-size: 14px;
color: #8E9095;
}
.ksapc-select-write-tile {
width: 100%;
}
.ksapc-checkboxgroup {
width: 100%;
}
.ksapc-row {
display: flex;
flex-wrap: wrap;
gap: 14px;
}
.ksapc-col {
flex: 1 1 48%; /* 两列布局 */
}
.ksapc-checkbox {
display: flex;
align-items: center;
}
.ksapc-checkbox input {
margin-right: 8px;
}
.ksapc-checkbox span{
font-size: 14px;
cursor: pointer;
}
#onload{
width: 20vw;
height: 5vw;
min-width: 200px;
min-height: 45px;
background-color: #0A6CFF;
color: white;
border-radius: 10px;
line-height: 5vw;
text-align: center;
font-size: 15px;
font-weight: bold;
margin-bottom: 35px;
cursor: pointer; /* 添加小手图标 */
}
</style>
</head>
<body id="box_k">
<div class="big_box">
<div class="content">
<img src="/tsf/business_title.jpg" alt="">
<div class="content_c">
<div class="title_t">商务合作意向登记表</div>
<div class="title_c2">
智能设备产品包<span>含身高测量仪、体重体脂秤、宠物秤, 母婴秤,厨房秤,商业秤,身高体重/体脂秤,八电极体脂秤,运动训练设备</span>等;软件包含就智能健康管理系统,智能硬件管理系统等,支持智能设备选购/定制、健康系统对接/定制行业解决方案等您也可以直接拨打或微信联系13590959084期待与您合作
</div>
<div class="write_box">
<div class="write_box_t">
<span class="write_box_r">*</span>&nbsp; 1.客户姓名
</div>
<div class="write_k">
<textarea placeholder="请输入" rows="1" oninput="autoResize(this)" class="name-input"></textarea>
</div>
</div>
<div class="write_box">
<div class="write_box_t">
<span class="write_box_r">*</span>&nbsp; 2.联系电话
</div>
<div class="write_k">
<textarea placeholder="请输入手机号" rows="1" oninput="autoResize(this)" class="phone-input"></textarea>
</div>
</div>
<div class="write_box">
<div class="write_box_t">
<span class="write_box_r">*</span>&nbsp; 3.公司名称
</div>
<div class="write_k">
<textarea placeholder="请输入" rows="1" oninput="autoResize(this)" class="company-input"></textarea>
</div>
</div>
<div class="write_box">
<div class="write_box_t">
<span class="write_box_r">*</span>&nbsp; 4.合作意向
</div>
<div class="write_k" style="border: none;">
<div class="ksapc-select-write">
<div class="ksapc-select-write-tip" id="selectedCount">此题已选择 0/6 项</div>
<div class="ksapc-select-write-tile">
<div class="ksapc-checkboxgroup">
<div class="ksapc-row">
<div class="ksapc-col">
<label class="ksapc-checkbox">
<input type="checkbox" class="option-checkbox" value="智能设备">
<span>智能设备</span>
</label>
</div>
<div class="ksapc-col">
<label class="ksapc-checkbox">
<input type="checkbox" class="option-checkbox" value="健康软件">
<span>健康软件</span>
</label>
</div>
<div class="ksapc-col">
<label class="ksapc-checkbox">
<input type="checkbox" class="option-checkbox" value="解决方案">
<span>解决方案</span>
</label>
</div>
<div class="ksapc-col">
<label class="ksapc-checkbox">
<input type="checkbox" class="option-checkbox" value="系统定制">
<span>系统定制</span>
</label>
</div>
<div class="ksapc-col">
<label class="ksapc-checkbox">
<input type="checkbox" class="option-checkbox" value="设备定制">
<span>设备定制</span>
</label>
</div>
<div class="ksapc-col">
<label class="ksapc-checkbox">
<input type="checkbox" class="option-checkbox" value="其它">
<span>其它可联系商务合作13590959084</span>
</label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="write_box">
<div class="write_box_t">
<span class="write_box_r">*</span>&nbsp; 5.备注
</div>
<div class="write_k">
<textarea placeholder="请输入" rows="1" oninput="autoResize(this)" class="remark-input"></textarea>
</div>
</div>
<div class="write_box" style="color: #8E9095;">
商务合作电话/微信13590959084
</div>
</div>
<div id="onload">提交</div>
</div>
</div>
</body>
</html>
<script>
var selectedValues = [];
function autoResize(textarea) {
textarea.style.height = 'auto'; // 重置高度
textarea.style.height = textarea.scrollHeight + 'px'; // 设置为内容高度
}
document.addEventListener('DOMContentLoaded', function() {
// 获取 #onload 元素
const onloadElement = document.getElementById('onload');
// 计算 #onload 元素的高度
const height = onloadElement.offsetHeight;
// 设置 #onload 元素的行高与高度一致
onloadElement.style.lineHeight = height + 'px';
const checkboxes = document.querySelectorAll('.option-checkbox');
const selectedCountElement = document.getElementById('selectedCount');
let selectedCount = 0;
function updateSelectedCount() {
selectedCount = 0;
selectedValues = [];
checkboxes.forEach(checkbox => {
if (checkbox.checked) {
selectedCount++;
selectedValues.push(checkbox.value);
}
});
selectedCountElement.textContent = `此题已选择 ${selectedCount}/6 项`;
console.log('Selected Values:', selectedValues);
}
checkboxes.forEach(checkbox => {
checkbox.addEventListener('change', updateSelectedCount);
});
$('#onload').on('click', function() {
// 获取所有需要检查的输入字段
const nameInput = document.querySelector('.name-input');
const phoneInput = document.querySelector('.phone-input');
const companyInput = document.querySelector('.company-input');
const remarkInput = document.querySelector('.remark-input');
// 检查每个字段是否为空
let hasError = false;
let errorMessage = '';
if (!nameInput || nameInput.value.trim() === '') {
hasError = true;
errorMessage += '1. 客户姓名\n';
}
if (!phoneInput || phoneInput.value.trim() === '') {
hasError = true;
errorMessage += '2. 联系电话\n';
}
if (!companyInput || companyInput.value.trim() === '') {
hasError = true;
errorMessage += '3. 公司名称\n';
}
if (selectedCount === 0) {
hasError = true;
errorMessage += '4. 合作意向\n';
}
if (!remarkInput || remarkInput.value.trim() === '') {
hasError = true;
errorMessage += '5. 备注\n';
}
if (hasError) {
layer.msg('以下项目未填写或未选择:\n' + errorMessage, {icon: 2});
// alert('以下项目未填写或未选择:\n' + errorMessage);
return;
}
var index = layer.load(1, {
shade: [0.1, '#fff'] //0.1透明度的白色背景
});
// 如果所有字段都填写了,执行提交操作
$.ajax({
url: "business_cooperation_action", // 请求的url地址
dataType: "json", // 返回格式为json
async: true, // 请求是否异步默认为异步这也是ajax重要特性
data: {
"name": nameInput.value,
"phone": phoneInput.value,
"company": companyInput.value,
"selectedValues": selectedValues,
"remark": remarkInput.value
},
type: "POST", // 请求方式
success: function(req) {
layer.close(layer.index)
// 请求成功时处理
if(req.code == 0){
layer.msg(req.msg, {icon: 1});
setTimeout(() => {
window.location.reload();
}, 2000);
}else{
layer.msg(req.msg, {icon: 2});
}
},
error: function() {
layer.close(layer.index)
// 请求出错处理
layer.msg('网络错误了,请直接联系商务合作电话/微信13590959084', {icon: 2});
}
});
});
});
</script>

View File

@ -11,27 +11,26 @@ class Qrcode extends Base{
public function ordinary_code(){
// $num = Db::table('app_version_log')->order('id desc')->find();
echo '你好,这里仅仅是个展示页面-配合小白快乐成长&宠物小白使用';
// echo '你好,这里仅仅是个展示页面-配合小白快乐成长&宠物小白使用';
// echo '<br><a href="'.$num['download_url'].'">点击下载</a>';
// $url = Db::table('app_version_log')->order('id desc')->find();
// $this->assign([
// 'url' => $url['download_url'],
// ]);
// return $this->fetch();
return $this->fetch();
}
public function bluetooth_code(){
// $num = Db::table('app_version_log')->order('id desc')->find();
echo '你好,这里仅仅是个展示页面-配合reedaw&宠物小白使用';
// echo '<br><a href="'.$num['download_url'].'">点击下载</a>';
// $url = Db::table('app_version_log')->order('id desc')->find();
// $this->assign([
$url = Db::table('app_version_log')->order('id desc')->find();
$this->assign([
// 'url' => $url['download_url'],
// ]);
// return $this->fetch();
'url' => $url['download_url'],
]);
return $this->fetch();
}
}

View File

@ -1,218 +0,0 @@
<!DOCTYPE html>
<html class="x-admin-sm">
<head>
<meta charset="UTF-8">
<title>app版本管理</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />
<link rel="stylesheet" href="/x_admin/css/font.css">
<link rel="stylesheet" href="/x_admin/css/xadmin.css">
<script type="text/javascript" src="/x_admin/lib/layui/layui.js" charset="utf-8"></script>
<script type="text/javascript" src="/x_admin/js/xadmin.js"></script>
<script type="text/javascript" src="/x_admin/js/jq.js"></script>
<!-- 让IE8/9支持媒体查询从而兼容栅格 -->
<!--[if lt IE 9]>
<script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
<script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="layui-fluid">
<div class="layui-row">
<form class="layui-form">
<div class="layui-form-item">
<label for="L_email" class="layui-form-label">
<span class="x-red"></span>卡片图标</label>
</label>
<div class="layui-input-inline">
<!-- <input type="text" id="L_email" name="email" required="" lay-verify="email" autocomplete="off" class="layui-input"> -->
<input type="file" id="upload_file_app" lay-verify="upload_file_app" name="file_data">
</div>
<!-- <div class="layui-form-mid layui-word-aux">
<span class="x-red">*</span>将会成为您唯一的登入名
</div> -->
</div>
<div class="layui-form-item">
<label for="card_name" class="layui-form-label">
<span class="x-red"></span>卡片名称</label>
<div class="layui-input-inline">
<input type="text" id="card_name" name="card_name" required="" lay-verify="card_name" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label for="page_url_record" class="layui-form-label">
<span class="x-red">*</span>手动记录路径</label>
<div class="layui-input-inline">
<input type="text" id="page_url_record" name="page_url_record" required="" lay-verify="page_url_record" autocomplete="off" class="layui-input"></div>
<div class="layui-form-mid layui-word-aux"></div>
</div>
<div class="layui-form-item">
<label for="page_url_report" class="layui-form-label">
<span class="x-red">*</span>报告页路径</label>
<div class="layui-input-inline">
<input type="text" id="page_url_report" name="page_url_report" required="" lay-verify="page_url_report" autocomplete="off" class="layui-input"></div>
<div class="layui-form-mid layui-word-aux"></div>
</div>
<div class="layui-form-item">
<label for="page_url_bluetooth" class="layui-form-label">
<span class="x-red">*</span>蓝牙路径</label>
<div class="layui-input-inline">
<input type="text" id="page_url_bluetooth" name="page_url_bluetooth" required="" lay-verify="page_url_bluetooth" autocomplete="off" class="layui-input"></div>
<div class="layui-form-mid layui-word-aux"></div>
</div>
<div class="layui-form-item">
<label for="content" class="layui-form-label">
<span class="x-red">*</span>描述</label>
<div class="layui-input-inline">
<input type="text" id="content" name="content" required="" lay-verify="content" autocomplete="off" class="layui-input"></div>
</div>
<div class="layui-form-item">
<label for="L_repass" class="layui-form-label"></label>
<!-- <div class="layui-btn" id="add" lay-filter="add" lay-submit="">增加</div>
<input value="登录" lay-submit lay-filter="add" type="submit" class="layui-btn"> -->
<button class="layui-btn" lay-filter="add" lay-submit="">增加</button>
</div>
</form>
</div>
</div>
<script>
$(document).ready(function(){
var file_name_all = ''
var file_name = ''
var file_extension = ''
var pd = true
$('#upload_file_app').on('change', function() {
// 获取被选择的文件
var fileInput = $(this)[0];
var file = fileInput.files[0];
// 检查是否有文件被选择
if (file) {
// 获取文件的名称
file_name_all = file.name;
// 使用lastIndexOf和substring来获取文件名不包括后缀
var lastIndex = file_name_all.lastIndexOf('.');
file_name = lastIndex !== -1 ? file_name_all.substring(0, lastIndex) : file_name_all;
// 获取文件后缀
file_extension = lastIndex !== -1 ? file_name_all.substring(lastIndex + 1) : '';
$('#file_name').val(file_name)
console.log(file_name)
console.log(file_extension)
// formdata.append('apk',$('#upload_file_app')[0].files[0])
}
});
function add_data(){
if(pd === false){
return
}
var formdata = new FormData();
formdata.append('upload_file_app',$('#upload_file_app')[0].files[0])
formdata.append('card_name',$('#card_name').val())
formdata.append('page_url_record',$('#page_url_record').val())
formdata.append('page_url_report',$('#page_url_report').val())
formdata.append('page_url_bluetooth',$('#page_url_bluetooth').val())
formdata.append('content',$('#content').val())
formdata.append('file_extension',file_extension)
load()
pd = false
console.log('进来了')
$.ajax({
url:"/card/card_add_action", //请求的url地址
contentType:false,
processData:false,
async:true,//请求是否异步默认为异步这也是ajax重要特性
data:formdata, //参数值
type:"POST", //请求方式
success:function(req){
c_load()
pd = true
if(req.code == 0){
layer.alert("增加成功", {icon: 6},function() {
//关闭当前frame
xadmin.close();
// 可以对父窗口进行刷新
xadmin.father_reload();
});
}else{
layer.alert("增加失败"+req.msg, {icon: 6},function() {
//关闭当前frame
xadmin.close();
// 可以对父窗口进行刷新
xadmin.father_reload();
});
}
//请求成功时处理
console.log(req)
},
error:function(){
//请求出错处理
pd = true
}
});
}
layui.use(['form', 'layer','jquery'],function() {
$ = layui.jquery;
var form = layui.form,
layer = layui.layer;
//自定义验证规则
form.verify({
upload_file_app: function(value) {
if (value == '') {
return '请先选择文件';
}
},
card_name: function(value) {
if (value == '') {
return '必须填写文件名';
}
},
// version_num: [/[\d.]{0,9}$/, '版本号必须以大写V开头最多10个字符由数字跟英文"."组成)'],
content: function(value) {
if (value == '') {
return '必须填写描述';
}
},
});
//监听提交
form.on('submit(add)',function(data) {
//发异步把数据提交给php
add_data()
return false;
});
});
//加载提示开启
function load() {
var index = layer.load(1, {
shade: [0.1, '#fff'] //0.1透明度的白色背景
});
}
// 关闭加载提示
function c_load() {
layer.close(layer.index)
}
});
// });
</script>
</body>
</html>

View File

@ -1,232 +0,0 @@
<!DOCTYPE html>
<html class="x-admin-sm">
<head>
<meta charset="UTF-8">
<title>app版本管理</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />
<link rel="stylesheet" href="/x_admin/css/font.css">
<link rel="stylesheet" href="/x_admin/css/xadmin.css">
<script type="text/javascript" src="/x_admin/lib/layui/layui.js" charset="utf-8"></script>
<script type="text/javascript" src="/x_admin/js/xadmin.js"></script>
<script type="text/javascript" src="/x_admin/js/jq.js"></script>
<!-- 让IE8/9支持媒体查询从而兼容栅格 -->
<!--[if lt IE 9]>
<script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
<script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="layui-fluid">
<div class="layui-row">
<form class="layui-form">
<div class="layui-form-item">
<label for="L_email" class="layui-form-label">
<span class="x-red"></span>卡片图标</label>
</label>
<div class="layui-input-inline">
<!-- <input type="text" id="L_email" name="email" required="" lay-verify="email" autocomplete="off" class="layui-input"> -->
<input type="file" id="upload_file_app" lay-verify="upload_file_app" name="file_data">
</div>
<!-- <div class="layui-form-mid layui-word-aux">
<span class="x-red">*</span>将会成为您唯一的登入名
</div> -->
</div>
<div class="layui-form-item">
<label for="card_name" class="layui-form-label">
<span class="x-red"></span>卡片名称</label>
<div class="layui-input-inline">
<input type="text" id="card_name" name="card_name" required="" lay-verify="card_name" autocomplete="off" class="layui-input" value="{$result.name}">
</div>
</div>
<div class="layui-form-item">
<label for="page_url_record" class="layui-form-label">
<span class="x-red">*</span>手动记录路径</label>
<div class="layui-input-inline">
<input type="text" id="page_url_record" name="page_url_record" required="" lay-verify="page_url_record" autocomplete="off" class="layui-input" value="{$result.page_url_record}"></div>
<div class="layui-form-mid layui-word-aux"></div>
</div>
<div class="layui-form-item">
<label for="page_url_report" class="layui-form-label">
<span class="x-red">*</span>报告页路径</label>
<div class="layui-input-inline">
<input type="text" id="page_url_report" name="page_url_report" required="" lay-verify="page_url_report" autocomplete="off" class="layui-input" value="{$result.page_url_report}"></div>
<div class="layui-form-mid layui-word-aux"></div>
</div>
<div class="layui-form-item">
<label for="page_url_bluetooth" class="layui-form-label">
<span class="x-red">*</span>蓝牙路径</label>
<div class="layui-input-inline">
<input type="text" id="page_url_bluetooth" name="page_url_bluetooth" required="" lay-verify="page_url_bluetooth" autocomplete="off" class="layui-input" value="{$result.page_url_bluetooth}"></div>
<div class="layui-form-mid layui-word-aux"></div>
</div>
<div class="layui-form-item">
<label for="content" class="layui-form-label">
<span class="x-red">*</span>描述</label>
<div class="layui-input-inline">
<input type="text" id="content" name="content" required="" lay-verify="content" autocomplete="off" class="layui-input" value="{$result.content}"></div>
</div>
<div class="layui-form-item">
<label for="L_repass" class="layui-form-label"></label>
<!-- <div class="layui-btn" id="add" lay-filter="add" lay-submit="">增加</div>
<input value="登录" lay-submit lay-filter="add" type="submit" class="layui-btn"> -->
<button class="layui-btn" lay-filter="add" lay-submit="">修改</button>
</div>
</form>
</div>
</div>
<!-- <div class="layui-fluid">
<div id="official_1" class="layui-row">
<div style="margin-left: 8%;margin-top: 5%;font-size: 25px;">请先下载模板文件,信息填写完成并上传该文件后点击生成</div>
<img style="width: 90%;margin-left: 3%;"src="/uploads/code_demo.png?v=1.0" alt="">
<div class="layui-form-item" style="width: 30%;margin-left: 33%;margin-top: 5%;">
<span>步骤1</span><a href="/uploads/code_demo.xlsx" class="layui-btn" lay-filter="add">下载模板文件</a>
</div>
<div class="layui-form-item" style="width: 50%;margin-left: 33%;margin-top: 5%;">
<span>步骤2</span><input type="file" id="data_excel" name="data_excel">
</div>
<div class="layui-form-item" style="width: 30%;margin-left: 33%;margin-top: 5%;">
<span>步骤3</span><button class="layui-btn" lay-filter="add" lay-submit="" onclick="add_data()">生成</button>
</div>
</div>
</div> -->
<script>
$(document).ready(function(){
var id = "{$result.id}"
var file_name_all = ''
var file_name = ''
var file_extension = ''
var pd = true
$('#upload_file_app').on('change', function() {
// 获取被选择的文件
var fileInput = $(this)[0];
var file = fileInput.files[0];
// 检查是否有文件被选择
if (file) {
// 获取文件的名称
file_name_all = file.name;
// 使用lastIndexOf和substring来获取文件名不包括后缀
var lastIndex = file_name_all.lastIndexOf('.');
file_name = lastIndex !== -1 ? file_name_all.substring(0, lastIndex) : file_name_all;
// 获取文件后缀
file_extension = lastIndex !== -1 ? file_name_all.substring(lastIndex + 1) : '';
$('#file_name').val(file_name)
// console.log($('#upload_file_app')[0].files[0])
// formdata.append('apk',$('#upload_file_app')[0].files[0])
}
});
function edit_data(){
if(pd === false){
return
}
var formdata = new FormData();
formdata.append('upload_file_app',$('#upload_file_app')[0].files[0])
formdata.append('card_name',$('#card_name').val())
formdata.append('page_url_record',$('#page_url_record').val())
formdata.append('page_url_report',$('#page_url_report').val())
formdata.append('page_url_bluetooth',$('#page_url_bluetooth').val())
formdata.append('content',$('#content').val())
formdata.append('file_extension',file_extension)
formdata.append('id',id)
load()
pd = false
console.log('进来了')
$.ajax({
url:"/card/card_edit_action", //请求的url地址
contentType:false,
processData:false,
async:true,//请求是否异步默认为异步这也是ajax重要特性
data:formdata, //参数值
type:"POST", //请求方式
success:function(req){
c_load()
pd = true
if(req.code == 0){
layer.alert("修改成功", {icon: 6},function() {
//关闭当前frame
xadmin.close();
// 可以对父窗口进行刷新
xadmin.father_reload();
});
}else{
layer.alert("修改失败"+req.msg, {icon: 6},function() {
//关闭当前frame
xadmin.close();
// 可以对父窗口进行刷新
xadmin.father_reload();
});
}
//请求成功时处理
console.log(req)
},
error:function(){
//请求出错处理
pd = true
}
});
}
layui.use(['form', 'layer','jquery'],function() {
$ = layui.jquery;
var form = layui.form,
layer = layui.layer;
//自定义验证规则
form.verify({
// upload_file_app: function(value) {
// if (value == '') {
// return '请先选择文件';
// }
// },
file_name: function(value) {
if (value == '') {
return '必须填写文件名';
}
},
// version_num: [/[\d.]{0,9}$/, '版本号必须以大写V开头最多10个字符由数字跟英文"."组成)'],
content: function(value) {
if (value == '') {
return '必须填写描述';
}
},
});
//监听提交
form.on('submit(add)',function(data) {
//发异步把数据提交给php
edit_data()
return false;
});
});
//加载提示开启
function load() {
var index = layer.load(1, {
shade: [0.1, '#fff'] //0.1透明度的白色背景
});
}
// 关闭加载提示
function c_load() {
layer.close(layer.index)
}
});
// });
</script>
</body>
</html>

View File

@ -0,0 +1,234 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, initial-scale=1,minimum-scale=1, maximum-scale=1,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta http-equiv="Access-Control-Allow-Origin" content="*">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="format-detection" content="telephone=no, email=no">
<meta name="full-screen" content="true">
<meta name="screen-orientation" content="portrait">
<meta name="x5-fullscreen" content="true">
<meta name="360-fullscreen" content="true">
<title>跳转页</title>
<script src="/x_admin/js/jq.js"></script>
<style>
*{
padding: 0 0;
margin: 0 0;
}
.big_box{
width: 100vw;
height: 100vh;
position: absolute;
top: 0;
left: 0;
}
.content_1{
width: 100vw;
height: 100vh;
position: absolute;
top: 0;
left: 0;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
justify-content: flex-start;
align-items: center;
overflow: auto;
padding: 10vw;
box-sizing: border-box;
font-size: 4vw;
}
.download{
width: 60vw;
height: 18vw;
margin-bottom: 0vw;
margin-top: 10vw;
background: url('/download_img/code_qrcode_reedaw_app.png') no-repeat;
background-size: contain;
background-position: center;
}
.title{
width: 60vw;
height: 20vw;
margin-bottom: 0vw;
margin-top: 7vw;
background: url('/download_img/code_qrcode_title.png') no-repeat;
background-size: contain;
background-position: center;
}
.jump1{
width: 60vw;
height: 18vw;
margin-bottom: 0vw;
margin-top: 15vw;
background: url('/download_img/code_qrcode_reedaw_wechat.png') no-repeat;
background-size: contain;
background-position: center;
}
.jump2{
width: 60vw;
height: 18vw;
margin-bottom: 0vw;
margin-top: 10vw;
background: url('/download_img/code_qrcode_cwxb.png') no-repeat;
background-size: contain;
background-position: center;
}
.ts{
width: 100vw;
height: 100vh;
position: absolute;
top: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.8);
}
.ts_box{
width: 85vw;
height: 27vw;
position: absolute;
top: 20%;
left: 12%;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
justify-content: space-evenly;
align-items: flex-start;
font-size: 5vw;
color: white;
font-weight: bold;
}
.ts_pic{
width: 32vw;
height: 40vw;
position: absolute;
top: 0%;
right: 0%;
background: url(/tsf/registered_arrow.png) no-repeat;
background-size: contain;
background-position: center;
}
a{
margin-top: 10vw;
text-decoration: none;
color: blue;
}
.bouncing-button-container {
transform-origin: center bottom; /* 设置旋转的基点在底部中心 */
animation: rotateAndRaise 2s ease-in-out forwards infinite;
}
@keyframes rotateAndRaise {
0% {
transform: rotate(0deg) translateY(0); /* 初始状态,不旋转也不升高 */
}
10% {
transform: rotate(5deg); /* 初始状态,不旋转也不升高 */
}
20% {
transform: rotate(0deg) translateY(-50px); /* 50%时旋转15°并升高50px */
}
30% {
transform: rotate(-5deg); /* 初始状态,不旋转也不升高 */
}
40% {
transform: rotate(0deg) translateY(0px); /* 结束状态往右旋转30°并升高50px */
}
100% {
transform: rotate(0deg) translateY(0px); /* 结束状态往右旋转30°并升高50px */
}
}
.bottom_d{
width: 100vw;
height: 65vw;
position: absolute;
bottom: 0;
left: 0;
background: url('/download_img/bottom.png') no-repeat;
background-position: bottom;
background-size: contain;
}
</style>
</head>
<body id="box_k">
<div class="big_box">
<div class="content_1">
<div class="title"></div>
<div class="jump1" onclick="jump('reedaw')"></div>
<div class="download" onclick="download()"></div>
<div class="jump2" onclick="jump('cwxb')"></div>
<div class="bottom_d"></div>
</div>
</div>
<div class="ts" style="display: none;">
<div class="ts_box">
<div>1、点击右上角“ ··· ”</div>
<div>2、在菜单中选择“在浏览器中打开”</div>
</div>
<div class="ts_pic"></div>
</div>
</body>
</html>
<script>
var str_url = "{$url}";
function isWeixin() {
var ua = navigator.userAgent.toLowerCase();
return /micromessenger/i.test(ua);
}
function isIOS() {
var userAgent = navigator.userAgent || navigator.vendor || window.opera;
return /iPad|iPhone|iPod/.test(userAgent) && !window.MSStream;
}
function jump(){
// window.location.href = 'weixin://dl/business/?appid=wx3e50e84030fe0d1e&path=pages/index/index';
window.location.href = 'weixin://dl/business/?appid=wx9c0b7a436ada6d1e&path=pages/home/home';
}
$('.ts').on('click',function(){
$(this).hide()
})
// if(isWeixin() && !isIOS()){
// $('.ts').show()
// }else{
// // console.log('当前不在微信环境中');
// // $('.download').addClass('bouncing-button-container')
// }
function download(){
if (isIOS()) {
console.log('当前是iOS设备');
window.location.href = "https://apps.apple.com/app/reedaw/id6654906497";
}else{
if (isWeixin()) {
console.log('当前在微信环境中');
$('.ts').show()
}else{
console.log('当前不是iOS设备');
// 在这里执行非iOS设备下的代码
window.location.href = str_url;
}
}
}
function jump(str){
if(str == 'reedaw'){
window.location.href = 'weixin://dl/business/?appid=wx9c0b7a436ada6d1e&path=pages/home/home';
}else{
window.location.href = 'weixin://dl/business/?appid=wx82a3493aa3ef1b6a&path=pages/index/index';
}
}
</script>

View File

@ -0,0 +1,182 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, initial-scale=1,minimum-scale=1, maximum-scale=1,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta http-equiv="Access-Control-Allow-Origin" content="*">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="format-detection" content="telephone=no, email=no">
<meta name="full-screen" content="true">
<meta name="screen-orientation" content="portrait">
<meta name="x5-fullscreen" content="true">
<meta name="360-fullscreen" content="true">
<title>跳转页</title>
<script src="/x_admin/js/jq.js"></script>
<style>
*{
padding: 0 0;
margin: 0 0;
}
.big_box{
width: 100vw;
height: 100vh;
position: absolute;
top: 0;
left: 0;
}
.content_1{
width: 100vw;
height: 100vh;
position: absolute;
top: 0;
left: 0;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
justify-content: flex-start;
align-items: center;
overflow: auto;
padding: 10vw;
box-sizing: border-box;
font-size: 4vw;
}
.title{
width: 60vw;
height: 20vw;
margin-bottom: 0vw;
margin-top: 7vw;
background: url('/download_img/code_qrcode_title2.png') no-repeat;
background-size: contain;
background-position: center;
}
.jump1{
width: 60vw;
height: 18vw;
margin-bottom: 0vw;
margin-top: 20vw;
background: url('/download_img/code_qrcode_cwxb.png') no-repeat;
background-size: contain;
background-position: center;
}
.jump2{
width: 60vw;
height: 18vw;
margin-bottom: 0vw;
margin-top: 20vw;
background: url('/download_img/code_qrcode_xbklcz.png') no-repeat;
background-size: contain;
background-position: center;
}
.ts{
width: 100vw;
height: 100vh;
position: absolute;
top: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.8);
}
.ts_box{
width: 85vw;
height: 27vw;
position: absolute;
top: 20%;
left: 12%;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
justify-content: space-evenly;
align-items: flex-start;
font-size: 5vw;
color: white;
font-weight: bold;
}
.ts_pic{
width: 32vw;
height: 40vw;
position: absolute;
top: 0%;
right: 0%;
background: url(/tsf/registered_arrow.png) no-repeat;
background-size: contain;
background-position: center;
}
a{
margin-top: 10vw;
text-decoration: none;
color: blue;
}
.bouncing-button-container {
transform-origin: center bottom; /* 设置旋转的基点在底部中心 */
animation: rotateAndRaise 2s ease-in-out forwards infinite;
}
@keyframes rotateAndRaise {
0% {
transform: rotate(0deg) translateY(0); /* 初始状态,不旋转也不升高 */
}
10% {
transform: rotate(5deg); /* 初始状态,不旋转也不升高 */
}
20% {
transform: rotate(0deg) translateY(-50px); /* 50%时旋转15°并升高50px */
}
30% {
transform: rotate(-5deg); /* 初始状态,不旋转也不升高 */
}
40% {
transform: rotate(0deg) translateY(0px); /* 结束状态往右旋转30°并升高50px */
}
100% {
transform: rotate(0deg) translateY(0px); /* 结束状态往右旋转30°并升高50px */
}
}
.bottom_d{
width: 100vw;
height: 65vw;
position: absolute;
bottom: 0;
left: 0;
background: url('/download_img/bottom.png') no-repeat;
background-position: bottom;
background-size: contain;
}
</style>
</head>
<body id="box_k">
<div class="big_box">
<div class="content_1">
<div class="title"></div>
<div class="jump1" onclick="jump('cwxb')"></div>
<div class="jump2" onclick="jump('xbklcz')"></div>
<div class="bottom_d"></div>
</div>
</div>
</body>
</html>
<script>
function isWeixin() {
var ua = navigator.userAgent.toLowerCase();
return /micromessenger/i.test(ua);
}
function isIOS() {
var userAgent = navigator.userAgent || navigator.vendor || window.opera;
return /iPad|iPhone|iPod/.test(userAgent) && !window.MSStream;
}
function jump(str){
if(str == 'xbklcz'){
window.location.href = 'weixin://dl/business/?appid=wx3e50e84030fe0d1e&path=pages/index/index';
}else{
window.location.href = 'weixin://dl/business/?appid=wx82a3493aa3ef1b6a&path=pages/index/index';
}
}
</script>

View File

@ -240,4 +240,30 @@ return [
'var_page' => 'page',
'list_rows' => 15,
],
// 第二个数据库配置(厨房秤)
'cfc_db' => [
// 数据库类型
'type' => 'sqlsrv',
// 服务器地址
'hostname' => '121.36.67.254',
// 'hostname' => '127.0.0.1',
// 数据库名
'database' => 'kitchen_scale',
// 用户名
'username' => 'jt_user',
// 密码
'password' => 'jtuser1qaz@WSX',
// 端口
'hostport' => '4331',
// 数据库连接参数
'params' => [],
// 数据库编码默认采用utf8
'charset' => 'utf8',
// 数据库表前缀
'prefix' => '',
// 数据库调试模式
'debug' => true,
],
];

View File

@ -53,4 +53,6 @@ return [
'datetime_format' => 'Y-m-d H:i:s',
// 是否需要进行SQL性能分析
'sql_explain' => false,
// 更多的数据库连接配置(例如:第二个数据库)
];

View File

@ -21,6 +21,13 @@ Route::any('/testedition/download', 'testapp/download/demo');
Route::any('/ceshi', 'app/download/ceshi');
Route::any('/get_class', 'admin/demo/get_class_xuesheng');
// 商务合作页面
Route::any('/business_cooperation', 'app/download/business_cooperation');
Route::any('/testedition/business_cooperation', 'testapp/download/business_cooperation');
Route::any('/business_cooperation_action', 'app/download/business_cooperation_action');
// // ################################################################二维码入口################################################################
// // ################################################################二维码入口################################################################
// 配合小白快乐成长&宠物小白使用
@ -28,8 +35,13 @@ Route::any('/ordinary_code', 'code/qrcode/ordinary_code');
// 配合reedaw&宠物小白使用
Route::any('/bluetooth_code', 'code/qrcode/bluetooth_code');
// // ################################################################设备请求入口################################################################
// // ################################################################设备请求入口################################################################
Route::any('/device_api_1', 'admin/device/device_request_api');
// Route::any('/CityList.js', 'tsf/CityList.js');
Route::any('/see_device_msg', 'admin/device/see_device_msg');
// // ################################################################管理后台################################################################
// // ################################################################管理后台################################################################
@ -113,7 +125,12 @@ Route::any('/notice/pop_edit', 'admin/notice/pop_edit');
Route::any('/notice/pop_add_or_update_action', 'admin/notice/pop_add_or_update_action');
Route::any('/notice/pop_update_sort', 'admin/notice/pop_update_sort');
Route::any('/notice/pop_stop_run', 'admin/notice/pop_stop_run');
// 公告管理
// 商业合作
Route::any('/business/business_index', 'admin/business/business_index');
Route::any('/business/business_download', 'admin/business/business_download');
// 联系我们H5
@ -367,6 +384,54 @@ Route::any('/testedition/get_recommend_information', 'testapp/Msginformation/get
Route::any('/get_business_cooperation_url', 'app/Msginformation/get_business_cooperation_url');
Route::any('/testedition/get_business_cooperation_url', 'testapp/Msginformation/get_business_cooperation_url');
// 重定向微信
Route::any('/open_wechat_content', 'app/Msginformation/open_wechat_content');
###########################################################################################################################################
################################################################以上是Reedaw################################################################
################################################################下面是厨房秤################################################################
###########################################################################################################################################
// 公共内容################################################################
// 获取用户上传图片列表
Route::any('/kitchenscale/pic_chose_list', 'app/kitchenscale/app.base/pic_chose_list');
Route::any('/testedition/kitchenscale/pic_chose_list', 'app/kitchenscale/testapp.base/pic_chose_list');
// 用户多图上传接口
Route::any('/kitchenscale/pic_upload_action', 'app/kitchenscale/app.base/pic_upload_action');
Route::any('/testedition/kitchenscale/pic_upload_action', 'app/kitchenscale/testapp.base/pic_upload_action');
// 首页内容################################################################
// 获取配置类信息
Route::any('/kitchenscale/get_default_config', 'app/kitchenscale/app.index/get_default_config');
Route::any('/testedition/kitchenscale/get_default_config', 'app/kitchenscale/testapp.index/get_default_config');
// 获取首页页面展示数据
Route::any('/kitchenscale/get_homepage_information', 'app/kitchenscale/app.index/get_homepage_information');
Route::any('/testedition/kitchenscale/get_homepage_information', 'app/kitchenscale/testapp.index/get_homepage_information');
// 菜谱内容################################################################
// 添加菜谱
Route::any('/kitchenscale/add_cookbook', 'app/kitchenscale/app.cookbook/add_cookbook');
Route::any('/testedition/kitchenscale/add_cookbook', 'app/kitchenscale/testapp.cookbook/add_cookbook');
// 根据菜谱标签查询列表(首页用)
Route::any('/kitchenscale/find_by_cook_label', 'app/kitchenscale/app.cookbook/find_by_cook_label');
Route::any('/testedition/kitchenscale/find_by_cook_label', 'app/kitchenscale/testapp.cookbook/find_by_cook_label');
// 根据食材详细查找列表
Route::any('/kitchenscale/find_by_food', 'app/kitchenscale/app.cookbook/find_by_food');
Route::any('/testedition/kitchenscale/find_by_food', 'app/kitchenscale/testapp.cookbook/find_by_food');
// 查询食谱的详情
Route::any('/kitchenscale/cookbook_details', 'app/kitchenscale/app.cookbook/cookbook_details');
Route::any('/testedition/kitchenscale/cookbook_details', 'app/kitchenscale/testapp.cookbook/cookbook_details');
// 关注菜谱
Route::any('/kitchenscale/cookbook_follow', 'app/kitchenscale/app.cookbook/cookbook_follow');
Route::any('/testedition/kitchenscale/cookbook_follow', 'app/kitchenscale/testapp.cookbook/cookbook_follow');
// 收藏菜谱
Route::any('/kitchenscale/cookbook_like', 'app/kitchenscale/app.cookbook/cookbook_like');
Route::any('/testedition/kitchenscale/cookbook_like', 'app/kitchenscale/testapp.cookbook/cookbook_like');
@ -375,6 +440,7 @@ Route::any('/testedition/get_business_cooperation_url', 'testapp/Msginformation/
// // ################################################################其它测试################################################################
// // ################################################################其它测试################################################################
Route::any('/is_wechat', 'admin/download/is_wechat');
Route::any('/use_test', 'admin/base/use_test');
// Route::any('/skip_kcal_calculate', 'app/skip/skip_kcal_calculate');
// Route::any('/readexcel', 'admin/execlaa/readexcel');

View File

@ -615,6 +615,10 @@ class Base extends Controller{
// 处理身高体重的单位转换它们为cm和kg。
function convertHeightAndWeight($height, $weight) {
// 加 bcadd(,,20)
// 减 bcsub(,,20)
// 乘 bcmul(,,20)
// 除 bcdiv(,,20)
// 定义单位转换比例
$heightConversion = [
'cm' => 1,
@ -635,8 +639,17 @@ class Base extends Controller{
];
// 处理 height
if (preg_match('/([\d.]+)(cm|inch|ft-in)/', $height, $matches)) {
$heightValue = floatval($matches[1]);
// $heightValue = floatval($matches[1]);
$heightValue = $matches[1];
$heightUnit = $matches[2];
if($heightUnit == 'ft-in'){
// 如果单位为st:lb但是数据格式不对
$heightValue = str_replace($heightUnit, "", $height);
if(count(explode('-', $heightValue)) < 2){
$heightValue = str_replace("-", "", $heightValue);
$heightValue = $heightValue."-0";
}
}
if (isset($heightConversion[$heightUnit])) {
if (is_callable($heightConversion[$heightUnit])) {
$heightInCm = $heightConversion[$heightUnit]($heightValue);
@ -656,10 +669,19 @@ class Base extends Controller{
}
}
// 处理 weight
if (preg_match('/([\d.]+)(kg|斤|st:lb|lb)/', $weight, $matches)) {
$weightValue = floatval($matches[1]);
if (preg_match('/([\d.:]+)(kg|斤|st:lb|lb)/', $weight, $matches)) {
$weightValue = $matches[1];
$weightUnit = $matches[2];
if($weightUnit == 'st:lb'){
// 如果单位为st:lb但是数据格式不对
$weightValue = str_replace($weightUnit, "", $weight);
if(count(explode(':', $weightValue)) < 2){
$weightValue = str_replace(":", "", $weightValue);
$weightValue = $weightValue.":0";
}
}
if (isset($weightConversion[$weightUnit])) {
if (is_callable($weightConversion[$weightUnit])) {
$weightInKg = $weightConversion[$weightUnit]($weightValue);
@ -678,10 +700,10 @@ class Base extends Controller{
$weightInKg = false;
}
}
return [
'height_in_cm' => $heightInCm,
'weight_in_kg' => $weightInKg
'height_in_cm' => bcmul($heightInCm,1,2),
'weight_in_kg' => bcmul($weightInKg,1,2)
];
}

View File

@ -241,7 +241,7 @@ class Card extends Base{
// 设备记录
// $data = ['id'=>'2','time'=>'1991-04-20 10:10:10','height'=>'15.1','weight'=>'75.1']
// public function card_manual_recording_device($data = ['aud_id'=>'37','height'=>'169.60,inch','weight'=>'52.45,lb','adc'=>'520.3','token'=>'591b70e0d80b5fa6d77e6e1384453ab9']){
public function card_manual_recording_device($data = ['aud_id'=>'37','height'=>'169.60斤','weight'=>'52.45斤','adc'=>'520.3','token'=>'591b70e0d80b5fa6d77e6e1384453ab9']){
public function card_manual_recording_device($data = ['aud_id'=>'37','height'=>'6-10ft-in','weight'=>'2:5.07st:lb','adc'=>'520.3','token'=>'591b70e0d80b5fa6d77e6e1384453ab9']){
try {
// 你的业务逻辑
if(count(input('post.')) > 0){
@ -267,34 +267,7 @@ class Card extends Base{
}
$data['height'] = $temporary_data['height_in_cm'];
$data['weight'] = $temporary_data['weight_in_kg'];
// if(!$this->verify_data_is_ok($data['height'],'num')){
// return $this->msg(10005);
// }
// if(!$this->verify_data_is_ok($data['weight'],'num')){
// return $this->msg(10005);
// }
// $data['height'] = explode(',',$data['height']);
// if(count($data['height']) < 2){
// return $this->msg(10005);
// }
// if(!$this->verify_data_is_ok($data['height'][0],'num')){
// return $this->msg(10005);
// }
// if(!in_array($data['height'][1],$this->unit_data['height'])){
// return $this->msg(10005);
// }
// $data['weight'] = explode(',',$data['weight']);
// if(count($data['height']) < 2){
// return $this->msg(10005);
// }
// if(!$this->verify_data_is_ok($data['weight'][0],'num')){
// return $this->msg(10005);
// }
// if(!in_array($data['weight'][1],$this->unit_data['weight'])){
// return $this->msg(10005);
// }
die;
$data['time'] = date('Y-m-d H:i:s');
$data['acd_id'] = '2';
$return_data = $this->set_user_body_data($data,'by_device');
@ -898,7 +871,6 @@ class Card extends Base{
// // 这里开始转换不同单位的身高体重为cm跟kgend
// $adc_type = $type;
// $data['type'] = 1;
// 判断头围数据是否存在是否合理
if(array_key_exists('head_data', $data)){
if(!$this->verify_data_is_ok($data['head_data'],'num')){

View File

@ -1,36 +1,57 @@
<?php
namespace app\app\controller;
namespace app\testapp\controller;
use think\Controller;
use think\Db;
class Download extends Base{
public function demo(){
// $num = Db::table('app_version_log')->order('id desc')->find();
// echo '你好,这里仅仅是个下载展示页面-1';
// echo '<br><a href="'.$num['download_url'].'">点击下载</a>';
$url = Db::table('app_version_log')->order('id desc')->find();
$this->assign([
'url' => $url['download_url'],
]);
return $this->fetch();
}
public function demo2(){
$url = Db::table('app_version_log')->order('id desc')->find();
$this->assign([
'url' => $url['download_url'],
]);
return $this->fetch();
}
public function business_cooperation(){
return $this->fetch();
}
public function business_cooperation_action(){
$data = input();
$result = Db::table('admin_business_cooperation_log')->insert([
'name'=>$data['name'],
'tel'=>$data['phone'],
'company'=>$data['company'],
'intention_data'=>implode(',',$data['selectedValues']),
'notes_data'=>$data['remark'],
'create_time'=>date('Y-m-d H:i:s'),
]);
if($result){
return json(['code'=>0,'msg'=>'提交成功']);
}else{
return json(['code'=>10001,'msg'=>'网络错误,请直接联系商务合作电话/微信13590959084']);
}
}
#########################################################################其它#########################################################################
#########################################################################其它#########################################################################
#########################################################################其它#########################################################################
public function ceshi(){
$data = input();
$url = 'https://klcz.pcxbc.com/open-api/calc/healthcalc/bodyfat3';

View File

@ -1,6 +1,6 @@
<?php
namespace app\testapp\controller;
namespace app\app\controller;
use think\Db;
@ -25,9 +25,7 @@ class Msginformation extends Base{
// 获取板块,及板块下类型标签
public function get_sector_label_msg($data = ['token'=>'6441bf7dabea7b3360a30240d3b19fc5']){
try {
if(count(input('post.')) > 0){
$data = input('post.');
}
$data = input('post.');
if(!array_key_exists('token', $data)){
return $this->msg(10001);
}
@ -72,6 +70,10 @@ class Msginformation extends Base{
}
if(!$this->verify_data_is_ok($data['page'],'intnum')){
return $this->msg(10005);
}else{
if($data['page'] < 1){
return $this->msg(10005,'页码不能小于1');
}
}
$return_data = $this->get_sector_content_msg_action($data);
@ -131,7 +133,7 @@ class Msginformation extends Base{
}
// 获取公告文章信息列表&banner
public function get_recommend_information($data=['token'=>'6441bf7dabea7b3360a30240d3b19fc5']){
// try {
try {
if(count(input('post.')) > 0){
$data = input('post.');
}
@ -145,19 +147,19 @@ class Msginformation extends Base{
$return_result = $this->get_recommend_information_action($data);
$this->record_api_log($data, null, $return_result);
return $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'] .= "行号: " . $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'] .= "代码: " . $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);
}
}
// 获取商务合作链接
@ -214,6 +216,38 @@ class Msginformation extends Base{
return $this->msg(99999);
}
}
// 给微信使用的中间页(拉起微信)
// public function open_wechat_content($data=['id'=>8]){
public function open_wechat_content(){
try {
$data = input();
if(!array_key_exists('id', $data)){
$this->record_api_log($data, null, ['code'=>10001,'msg'=>'',[]]);
return $this->msg(10001);
}
$url = Db::table('admin_notice_banner')->where(['id'=>$data['id']])->field('type,jump_url')->find();
if(!$url['type'] || $url['type'] != 2){
echo '<div style="font-size: 30px;font-weight: bold;">页面跑丢了... =。=</div>';
die;
}
header('Location: '.$url['jump_url']);
} 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'] .= "行号: " . $e->getLine() . "\n";
$logContent['all_content'] .= "跟踪信息:\n" . $e->getTraceAsString() . "\n";
$this->record_api_log($data, $logContent, null);
return $this->msg(99999);
}
}
################################################################业务################################################################
################################################################get_sector_label_msg
public function get_sector_label_msg_action($data){
@ -264,7 +298,8 @@ class Msginformation extends Base{
");
if(count($loop_result) > 0){
foreach ($loop_result as $k => $v) {
$loop_result[$key]['jump_url'] = "https://tc.pcxbc.com/editortext/model_content?id=".$v['id']."&token=".$data['token'];
// $loop_result[$key]['jump_url'] = "https://tc.pcxbc.com/editortext/model_content?id=".$v['id']."&token=".$data['token'];
$loop_result[$key]['jump_url'] = "https://tc.pcxbc.com/editortext/model_content";
}
}
$Template_arr[$value]['loop_data'] = $loop_result;
@ -307,7 +342,8 @@ class Msginformation extends Base{
");
if(count($content_result) > 0){
foreach ($content_result as $key => $value) {
$content_result[$key]['jump_url'] = "https://tc.pcxbc.com/editortext/model_content?id=".$value['id']."&token=".$data['token'];
// $content_result[$key]['jump_url'] = "https://tc.pcxbc.com/editortext/model_content?id=".$value['id']."&token=".$data['token'];
$content_result[$key]['jump_url'] = "https://tc.pcxbc.com/editortext/model_content";
}
}
$return_result['content_data'] = $content_result;
@ -390,7 +426,7 @@ class Msginformation extends Base{
'notice'=>[],
'banner'=>[]
];
return $this->msg($return_data);
// return $this->msg($return_data);
// 所有可用记录
$all_data = Db::table($this->msginformation_use_db_name['3'])->where(['is_del'=>0])->select();
// 用户阅读记录
@ -407,12 +443,14 @@ class Msginformation extends Base{
if($value['scene_data'] != 3){
unset($all_data[$key]);
}else{
$all_data[$key]['jump_url'] = $all_data[$key]['jump_url']."&token=".$data['token'];
// $all_data[$key]['jump_url'] = $all_data[$key]['jump_url']."&token=".$data['token'];
$all_data[$key]['jump_url'] = $all_data[$key]['jump_url'];
$all_data[$key]['type'] = 'h5';
$all_data[$key]['id'] = $value['parameter_data'];
}
}else{
$all_data[$key]['jump_url'] = $all_data[$key]['jump_url']."&token=".$data['token'];
// $all_data[$key]['jump_url'] = $all_data[$key]['jump_url']."&token=".$data['token'];
$all_data[$key]['jump_url'] = $all_data[$key]['jump_url'];
$all_data[$key]['type'] = 'h5';
$all_data[$key]['id'] = $value['parameter_data'];
}
@ -430,6 +468,9 @@ class Msginformation extends Base{
$all_data[$key]['appid'] = $appid;
$all_data[$key]['path'] = $path;
// 重新定义跳转链接为中间页
$all_data[$key]['jump_url'] = "https://tc.pcxbc.com/open_wechat_content";
}
// $all_data[$key]['id'] = $all_data[$key]['parameter_data'];
unset($all_data[$key]['parameter_data']);

View File

@ -0,0 +1,377 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, initial-scale=1,minimum-scale=1, maximum-scale=1,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta http-equiv="Access-Control-Allow-Origin" content="*">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="format-detection" content="telephone=no, email=no">
<meta name="full-screen" content="true">
<meta name="screen-orientation" content="portrait">
<meta name="x5-fullscreen" content="true">
<meta name="360-fullscreen" content="true">
<title>商务合作</title>
<script src="/x_admin/js/jq.js"></script>
<style>
*{
padding: 0 0;
margin: 0 0;
}
.big_box{
width: 100vw;
min-height: 100vh;
position: absolute;
top: 0;
left: 0;
background: url(/tsf/business_bg.jpg) no-repeat;
background-size: 100% 100%;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
align-items: center;
}
.content{
width: 85vw;
max-width: 880px;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
border-radius: 1vw;
background-color: white;
margin: 24px 0;
overflow: hidden;
align-items: center;
}
.content img{
width: 100%;
height: auto;
}
.content_c{
width: 100%;
padding: 2% 12%;
box-sizing: border-box;
}
.title_t{
border: none;
text-align: center;
color: rgba(8, 14, 23, 0.9);
font-weight: 600;
font-size: 28px;
line-height: 40px;
word-break: break-all;
white-space: pre-wrap;
overflow: visible;
margin: 4% 0;
}
.title_c2{
font-size: 12px;
margin-bottom: 10%;
}
.title_c2 span{
color: rgb(17, 106, 240);
}
.write_box{
width: 100%;
font-size: 16px;
margin: 10% 0;
}
.write_box_t{
font-weight: 600;
}
.write_box_r{
color: red;
}
.write_k{
padding: 8px 12px;
position: relative;
border-radius: 6px;
border: 1px solid rgba(8, 14, 23, 0.24);
display: flex;
outline: 0 !important;
word-break: break-all;
margin: 2% 0;
}
.write_k textarea{
width: 100%;
resize: none;
text-overflow: ellipsis;
line-height: 22px;
border: none !important;
border-radius: 0;
background: transparent !important;
box-shadow: none !important;
outline: 0 !important;
cursor: auto;
padding: 0;
min-height: 22px;
margin: 0 1%;
}
.ksapc-select-write {
width: 100%;
}
.ksapc-select-write-tip {
margin-bottom: 10px;
font-size: 14px;
color: #8E9095;
}
.ksapc-select-write-tile {
width: 100%;
}
.ksapc-checkboxgroup {
width: 100%;
}
.ksapc-row {
display: flex;
flex-wrap: wrap;
gap: 14px;
}
.ksapc-col {
flex: 1 1 48%; /* 两列布局 */
}
.ksapc-checkbox {
display: flex;
align-items: center;
}
.ksapc-checkbox input {
margin-right: 8px;
}
.ksapc-checkbox span{
font-size: 14px;
cursor: pointer;
}
#onload{
width: 20vw;
height: 5vw;
background-color: #0A6CFF;
color: white;
border-radius: 10px;
line-height: 5vw;
text-align: center;
font-size: 15px;
font-weight: bold;
margin-bottom: 35px;
cursor: pointer; /* 添加小手图标 */
}
</style>
</head>
<body id="box_k">
<div class="big_box">
<div class="content">
<img src="/tsf/business_title.jpg" alt="">
<div class="content_c">
<div class="title_t">商务合作意向登记表</div>
<div class="title_c2">
智能设备产品包<span>含身高测量仪、体重体脂秤、宠物秤, 母婴秤,厨房秤,商业秤,身高体重/体脂秤,八电极体脂秤,运动训练设备</span>等;软件包含就智能健康管理系统,智能硬件管理系统等,支持智能设备选购/定制、健康系统对接/定制行业解决方案等您也可以直接拨打或微信联系13590959084期待与您合作
</div>
<div class="write_box">
<div class="write_box_t">
<span class="write_box_r">*</span>&nbsp; 1.客户姓名
</div>
<div class="write_k">
<textarea placeholder="请输入" rows="1" oninput="autoResize(this)" class="name-input"></textarea>
</div>
</div>
<div class="write_box">
<div class="write_box_t">
<span class="write_box_r">*</span>&nbsp; 2.联系电话
</div>
<div class="write_k">
<textarea placeholder="请输入手机号" rows="1" oninput="autoResize(this)" class="phone-input"></textarea>
</div>
</div>
<div class="write_box">
<div class="write_box_t">
<span class="write_box_r">*</span>&nbsp; 3.公司名称
</div>
<div class="write_k">
<textarea placeholder="请输入" rows="1" oninput="autoResize(this)" class="company-input"></textarea>
</div>
</div>
<div class="write_box">
<div class="write_box_t">
<span class="write_box_r">*</span>&nbsp; 4.合作意向
</div>
<div class="write_k" style="border: none;">
<div class="ksapc-select-write">
<div class="ksapc-select-write-tip" id="selectedCount">此题已选择 0/6 项</div>
<div class="ksapc-select-write-tile">
<div class="ksapc-checkboxgroup">
<div class="ksapc-row">
<div class="ksapc-col">
<label class="ksapc-checkbox">
<input type="checkbox" class="option-checkbox" value="智能设备">
<span>智能设备</span>
</label>
</div>
<div class="ksapc-col">
<label class="ksapc-checkbox">
<input type="checkbox" class="option-checkbox" value="健康软件">
<span>健康软件</span>
</label>
</div>
<div class="ksapc-col">
<label class="ksapc-checkbox">
<input type="checkbox" class="option-checkbox" value="解决方案">
<span>解决方案</span>
</label>
</div>
<div class="ksapc-col">
<label class="ksapc-checkbox">
<input type="checkbox" class="option-checkbox" value="系统定制">
<span>系统定制</span>
</label>
</div>
<div class="ksapc-col">
<label class="ksapc-checkbox">
<input type="checkbox" class="option-checkbox" value="设备定制">
<span>设备定制</span>
</label>
</div>
<div class="ksapc-col">
<label class="ksapc-checkbox">
<input type="checkbox" class="option-checkbox" value="其它">
<span>其它可联系商务合作13590959084</span>
</label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="write_box">
<div class="write_box_t">
<span class="write_box_r">*</span>&nbsp; 5.备注
</div>
<div class="write_k">
<textarea placeholder="请输入" rows="1" oninput="autoResize(this)" class="remark-input"></textarea>
</div>
</div>
<div class="write_box" style="color: #8E9095;">
商务合作电话/微信13590959084
</div>
</div>
<div id="onload">提交</div>
</div>
</div>
</body>
</html>
<script>
var selectedValues = [];
function autoResize(textarea) {
textarea.style.height = 'auto'; // 重置高度
textarea.style.height = textarea.scrollHeight + 'px'; // 设置为内容高度
}
document.addEventListener('DOMContentLoaded', function() {
const checkboxes = document.querySelectorAll('.option-checkbox');
const selectedCountElement = document.getElementById('selectedCount');
let selectedCount = 0;
function updateSelectedCount() {
selectedCount = 0;
selectedValues = [];
checkboxes.forEach(checkbox => {
if (checkbox.checked) {
selectedCount++;
selectedValues.push(checkbox.value);
}
});
selectedCountElement.textContent = `此题已选择 ${selectedCount}/6 项`;
console.log('Selected Values:', selectedValues);
}
checkboxes.forEach(checkbox => {
checkbox.addEventListener('change', updateSelectedCount);
});
$('#onload').on('click', function() {
var index = layer.load(1, {
shade: [0.1, '#fff'] //0.1透明度的白色背景
});
// 获取所有需要检查的输入字段
const nameInput = document.querySelector('.name-input');
const phoneInput = document.querySelector('.phone-input');
const companyInput = document.querySelector('.company-input');
const remarkInput = document.querySelector('.remark-input');
// 检查每个字段是否为空
let hasError = false;
let errorMessage = '';
if (!nameInput || nameInput.value.trim() === '') {
hasError = true;
errorMessage += '1. 客户姓名\n';
}
if (!phoneInput || phoneInput.value.trim() === '') {
hasError = true;
errorMessage += '2. 联系电话\n';
}
if (!companyInput || companyInput.value.trim() === '') {
hasError = true;
errorMessage += '3. 公司名称\n';
}
if (selectedCount === 0) {
hasError = true;
errorMessage += '4. 合作意向\n';
}
if (!remarkInput || remarkInput.value.trim() === '') {
hasError = true;
errorMessage += '5. 备注\n';
}
if (hasError) {
alert('以下项目未填写或未选择:\n' + errorMessage);
return;
}
// 如果所有字段都填写了,执行提交操作
$.ajax({
url: "business_cooperation_action", // 请求的url地址
dataType: "json", // 返回格式为json
async: true, // 请求是否异步默认为异步这也是ajax重要特性
data: {
"name": nameInput.value,
"phone": phoneInput.value,
"company": companyInput.value,
"selectedValues": selectedValues,
"remark": remarkInput.value
},
type: "POST", // 请求方式
success: function(req) {
layer.close(layer.index)
// 请求成功时处理
layer.msg(req.msg, {icon: 2});
if(req.code == 0){
setTimeout(() => {
window.location.reload();
}, 1000);
}
},
error: function() {
layer.close(layer.index)
// 请求出错处理
alert('提交失败,请重试。');
}
});
});
});
</script>

View File

@ -30,6 +30,9 @@
"think-path": "thinkphp"
},
"config": {
"preferred-install": "dist"
"preferred-install": "dist",
"allow-plugins": {
"topthink/think-installer": true
}
}
}

View File

@ -0,0 +1,256 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>测试菜谱提交</title>
<style>
.ingredient, .step {
margin: 5px 0;
padding: 5px;
border: 1px solid #ccc;
}
.ingredient button, .step button {
margin-left: 10px;
}
.foot_list {
margin-top: 10px;
}
.foot_list .ingredient {
margin: 5px 0;
}
</style>
<script src="../x_admin/js/jq.js"></script>
</head>
<body>
<p style="font-weight: bold;">菜谱信息</p>
<div class='box1'>
<label for="cover">上传封面:</label>
<input type="file" id="cover" name="cover" accept="image/*" multiple>
<br>
<label for="title">菜谱标题:</label>
<input type="text" id="title" name="title">
<br>
<label for="description">菜谱简介:</label>
<textarea id="description" name="description" rows="4" cols="50"></textarea>
<br>
</div>
<p style="font-weight: bold;">添加食材</p>
<div class='box2'>
<div id="box2_content">
</div>
<div id="box2_action" style="margin:10px 0;display: flex;flex-direction: row;flex-wrap: nowrap;justify-content: space-around;">
<div onclick="clearIngredients()">清空</div>
<div onclick="addIngredient()">添加食材</div>
</div>
</div>
<p style="font-weight: bold;">编辑步骤</p>
<div class='box3'>
<div id="box3_content"></div>
<div id="box3_action">
<button onclick="addStep()">添加步骤</button>
</div>
</div>
<div onclick="saveData()" style="margin:50px 0;">保存</div>
</body>
</html>
<script>
var submit_data;
let ingredientsList = [];
function addIngredient() {
const ingredients = ['鸡肉', '牛肉', '猪肉'];
const randomIngredient = ingredients[Math.floor(Math.random() * ingredients.length)];
const randomWeight = Math.floor(Math.random() * (300 - 100 + 1)) + 100;
const ingredientDiv = document.createElement('div');
ingredientDiv.className = 'ingredient';
ingredientDiv.textContent = `${randomIngredient} ${randomWeight}克`;
const deleteButton = document.createElement('button');
deleteButton.textContent = '删除';
deleteButton.onclick = function() {
removeIngredient(ingredientDiv, randomIngredient, randomWeight);
};
ingredientDiv.appendChild(deleteButton);
document.getElementById('box2_content').appendChild(ingredientDiv);
ingredientsList.push({ name: randomIngredient, weight: randomWeight });
}
function removeIngredient(divElement, ingredientName, ingredientWeight) {
divElement.remove();
ingredientsList = ingredientsList.filter(item => !(item.name === ingredientName && item.weight === ingredientWeight));
}
function clearIngredients() {
const box2Content = document.getElementById('box2_content');
while (box2Content.firstChild) {
box2Content.removeChild(box2Content.firstChild);
}
ingredientsList = [];
}
function addStep() {
const stepDiv = document.createElement('div');
stepDiv.className = 'step';
// 多图上传
const fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.accept = 'image/*';
fileInput.name = 'images[]';
fileInput.multiple = true;
stepDiv.appendChild(fileInput);
// 选择食材按钮
const selectIngredientButton = document.createElement('button');
selectIngredientButton.textContent = '选择食材';
selectIngredientButton.onclick = function() {
selectIngredient(stepDiv);
};
stepDiv.appendChild(selectIngredientButton);
// 步骤输入说明
const stepDescription = document.createElement('textarea');
stepDescription.placeholder = '步骤说明';
stepDescription.rows = 4;
stepDescription.cols = 50;
stepDiv.appendChild(stepDescription);
// 每个步骤的 foot_list
const footList = document.createElement('div');
footList.className = 'foot_list';
stepDiv.appendChild(footList);
document.getElementById('box3_content').appendChild(stepDiv);
}
function selectIngredient(stepDiv) {
if (ingredientsList.length === 0) {
alert('没有可用的食材');
return;
}
// 获取当前步骤的 foot_list
const footList = stepDiv.querySelector('.foot_list');
// 获取已经添加过的食材
const addedIngredients = Array.from(footList.getElementsByClassName('ingredient')).map(div => div.textContent);
// 过滤已经添加过的食材
const availableIngredients = ingredientsList.filter(item => {
const ingredientText = `${item.name} ${item.weight}克`;
return !addedIngredients.includes(ingredientText);
});
if (availableIngredients.length === 0) {
alert('所有食材已添加');
return;
}
const randomIndex = Math.floor(Math.random() * availableIngredients.length);
const selectedIngredient = availableIngredients[randomIndex];
const ingredientDiv = document.createElement('div');
ingredientDiv.className = 'ingredient';
ingredientDiv.textContent = `${selectedIngredient.name} ${selectedIngredient.weight}克`;
const deleteButton = document.createElement('button');
deleteButton.textContent = '删除';
deleteButton.onclick = function() {
removeFootIngredient(ingredientDiv, selectedIngredient.name, selectedIngredient.weight, footList);
};
ingredientDiv.appendChild(deleteButton);
footList.appendChild(ingredientDiv);
}
function removeFootIngredient(divElement, ingredientName, ingredientWeight, footList) {
divElement.remove();
// 重新过滤 ingredientsList 以确保删除后不会重复添加
const addedIngredients = Array.from(footList.getElementsByClassName('ingredient')).map(div => div.textContent);
ingredientsList = ingredientsList.filter(item => {
const ingredientText = `${item.name} ${item.weight}克`;
return !addedIngredients.includes(ingredientText);
});
}
function saveData() {
const formData = new FormData();
// 封面文件
const coverInput = document.getElementById('cover');
if (coverInput.files.length > 0) {
formData.append('cover', coverInput.files[0]);
}
// 菜谱标题
const titleInput = document.getElementById('title');
formData.append('title', titleInput.value);
// 菜谱描述
const descriptionInput = document.getElementById('description');
formData.append('description', descriptionInput.value);
// 食材列表
formData.append('ingredientsList', JSON.stringify(ingredientsList));
// 步骤内容
const steps = document.querySelectorAll('.step');
steps.forEach((step, index) => {
// 步骤说明
const stepDescription = step.querySelector('textarea');
formData.append(`steps[${index}][description]`, stepDescription.value);
// 选择的食材
const footList = step.querySelector('.foot_list');
const ingredients = Array.from(footList.getElementsByClassName('ingredient')).map(div => {
const [name, weightText] = div.textContent.split(' ');
const weight = parseInt(weightText, 10);
return { name, weight };
});
formData.append(`steps[${index}][ingredients]`, JSON.stringify(ingredients));
// 上传的图片
const fileInput = step.querySelector('input[type="file"]');
Array.from(fileInput.files).forEach((file, fileIndex) => {
formData.append(`steps[${index}][images][${fileIndex}]`, file);
});
});
submit_data = formData;
// 打印 formData 内容
console.log('submit_data:', formData);
// 遍历 formData 以查看其内容
for (var pair of formData.entries()) {
console.log(pair[0] + ': ' + pair[1]);
}
$.ajax({
url: "http://wm.tcxbc.com/kitchenscale/add_cookbook", // 请求的url地址
contentType: false,
processData: false,
async: true, // 请求是否异步默认为异步这也是ajax重要特性
data: submit_data, // 参数值
type: "POST", // 请求方式
beforeSend: function() {
// 请求前的处理
},
success: function(req) {
// 请求成功时处理
console.log('成功:', req);
},
complete: function() {
// 请求完成的处理
},
error: function(err) {
// 请求出错处理
console.error('错误:', err);
}
});
}
</script>

View File

@ -0,0 +1,427 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>测试菜谱提交</title>
<style>
.yc{
display: none;
}
.ingredient, .step {
margin: 5px 0;
padding: 5px;
border: 1px solid #ccc;
}
.ingredient button, .step button {
margin-left: 10px;
}
.foot_list {
margin-top: 10px;
}
.foot_list .ingredient {
margin: 5px 0;
}
#fileInput{
display: none;
}
#img_chose{
width: 95vw;
height: 100vw;
background-color: #ccc;
position: absolute;
top: 20%;
left: 0;
right: 0;
margin: 0 auto;
display: none;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-around;
align-content: flex-start;
}
#img_chose img{
width:20vw;
height: 20vw;
}
.cover_show img{
width: 30%;
}
.step_show_all img{
width: 20%;
}
</style>
<script src="../x_admin/js/jq.js"></script>
</head>
<body>
<p style="font-weight: bold;">菜谱信息~</p>
<div class='box1'>
<label for="cover">上传封面:</label>
<button onclick="open_img_chose('cover',0)">选择图片</button>
<br>
<div class="cover_show"></div>
<br>
<br>
<label for="title">菜谱标题:</label>
<input type="text" id="title" name="title">
<br>
<br>
<label for="description">菜谱简介:</label>
<textarea id="description" name="description" rows="4" cols="50"></textarea>
<br>
</div>
<p style="font-weight: bold;">添加食材</p>
<div class='box2'>
<div id="box2_content">
</div>
<div id="box2_action" style="margin:10px 0;display: flex;flex-direction: row;flex-wrap: nowrap;justify-content: space-around;">
<div onclick="clearIngredients()">清空</div>
<div onclick="addIngredient()">添加食材</div>
</div>
</div>
<p style="font-weight: bold;">编辑步骤</p>
<div class='box3'>
<div id="box3_content"></div>
<div id="box3_action">
<button onclick="addStep()">添加步骤</button>
</div>
</div>
<div onclick="saveData()" style="margin:50px 0;">保存</div>
<!-- 图片选择组件 -->
<div id="img_chose" class="yc">
<div onclick="upload_action()"><img src="http://tc.pcxbc.com/tsf/upload_pic.jpg" alt=""></div>
<button onclick="close_action()">关闭</button>
</div>
<input type="file" id="fileInput" accept="image/*" name="img_list" multiple>
</body>
</html>
<script>
// 设置最终提交变量important
var post_data = {
"cook_label": '早餐', //菜谱标签,属于什么菜系之类的
"token": 'caadd1be045a65f30b92aa805f1de54a', //菜谱标签,属于什么菜系之类的
"cover": '', //封面图片
"title": '', //菜谱标题
"description": '', //菜谱简介
"food_list": [], //食材列表
"step_list": [], //步骤列表
};
var what_button = '';//用来判断是封面还是步骤
function open_img_chose(str,num){
what_button = str+','+num;
// $('#img_chose').html('');
var user_img_list = [];
$.ajax({
url:"https://tc.pcxbc.com/kitchenscale/pic_chose_list", //请求的url地址
// url:"http://wm.tcxbc.com/kitchenscale/pic_chose_list", //请求的url地址
dataType:"json", //返回格式为json
async:true,//请求是否异步默认为异步这也是ajax重要特性
data:{"token":"caadd1be045a65f30b92aa805f1de54a"}, //参数值
type:"POST", //请求方式
success:function(req){
if(req.code==0){
for (let index = 0; index < req.data.result.length; index++) {
var newDiv = $('<div></div>')
.addClass('pic_box')
.attr('onclick', 'sendParamToParent(\''+req.data.result[index]['id']+'\',\''+req.data.result[index]['pic_url']+'\',\''+what_button+'\')')
.append($('<img></img>')
.attr('src', req.data.result[index]['pic_url'])
.attr('alt', '')
);
$('#img_chose > div:first').after(newDiv);
}
$('#img_chose').css('display', 'flex');
}
},
error:function(){
//请求出错处理
}
});
}
function upload_action(){
document.getElementById('fileInput').click();
}
$('#fileInput').on('change', function() {
// 获取被选择的文件
var files = event.target.files;
if (files.length > 5) {
alert('最多只能选择5张图片,您选择了' + files.length + ' 张图片');
// 清空文件输入,取消选择的文件
$(this).val('');
return
}
console.log('当前选择了' + files.length + ' 张图片');
// 检查是否有文件被选择
if (files.length > 0) {
var formdata = new FormData();
for (var i = 0; i < files.length; i++) {
formdata.append('images[]', files[i]);
}
formdata.append('token', 'caadd1be045a65f30b92aa805f1de54a');
$.ajax({
url:"https://tc.pcxbc.com/kitchenscale/pic_upload_action", //请求的url地址
// url:"http://wm.tcxbc.com/kitchenscale/pic_upload_action", //请求的url地址
contentType:false,
processData:false,
async:true,//请求是否异步默认为异步这也是ajax重要特性
data:formdata, //参数值
type:"POST", //请求方式
success:function(req){
alert('本次添加失败'+req.data.error_data+'张');
for (let index = 0; index < req.data.insert_data.length; index++) {
var newDiv = $('<div></div>')
.addClass('pic_box')
.attr('onclick', 'sendParamToParent(\''+req.data.insert_data[index]['id']+'\',\''+req.data.insert_data[index]['pic_url']+'\',\''+what_button+'\')')
.append($('<img></img>')
.attr('src', req.data.insert_data[index]['pic_url'])
.attr('alt', '')
);
$('#img_chose > div:first').after(newDiv);
}
},
error:function(){
//请求出错处理
}
});
}
});
function sendParamToParent(id,url,parameter){
var parameter_arr = parameter.split(",");
if(parameter_arr[0] == 'cover'){
// 添加数据进最终提交变量important
post_data.cover = id;
$('.cover_show').html('');
$('.cover_show')
.append($('<img></img>')
.attr('src', url)
.attr('alt', '')
);
}else{
// 添加数据进最终提交变量important
post_data.step_list[parameter_arr[1]]['pic_list'].push(id);
$('.step_show_'+parameter_arr[1])
.append($('<img></img>')
.attr('src', url)
.attr('alt', '')
);
}
console.log(post_data)
}
function close_action(){
$('#img_chose').hide();
$('#img_chose .pic_box').remove();
}
</script>
<script>
var submit_data;
let ingredientsList = [];
// 添加随机的食材,从'鸡肉', '牛肉', '猪肉'随机选重量从100-300克随机选
function addIngredient() {
const ingredients = ['鸡肉', '牛肉', '猪肉'];
const randomIngredient = ingredients[Math.floor(Math.random() * ingredients.length)];
const randomWeight = Math.floor(Math.random() * (300 - 100 + 1)) + 100;
const ingredientDiv = document.createElement('div');
ingredientDiv.className = 'ingredient';
ingredientDiv.textContent = `${randomIngredient} ${randomWeight}克`;
const deleteButton = document.createElement('button');
deleteButton.textContent = '删除';
deleteButton.onclick = function() {
removeIngredient(ingredientDiv, randomIngredient, randomWeight);
};
ingredientDiv.appendChild(deleteButton);
document.getElementById('box2_content').appendChild(ingredientDiv);
post_data.food_list.push({ name: randomIngredient, weight: randomWeight });
console.log(post_data)
}
// 删除单个食材
function removeIngredient(divElement, ingredientName, ingredientWeight) {
divElement.remove();
post_data.food_list = post_data.food_list.filter(item => !(item.name === ingredientName && item.weight === ingredientWeight));
}
// 清除所有食材
function clearIngredients() {
const box2Content = document.getElementById('box2_content');
while (box2Content.firstChild) {
box2Content.removeChild(box2Content.firstChild);
}
post_data.food_list = [];
}
// 添加步骤
function addStep() {
const stepDiv = document.createElement('div');
stepDiv.className = 'step';
// 在步骤里面添加一个空数据
var num = post_data.step_list.push({ pic_list: [], foot_list: [] ,description:""});
// console.log(post_data.step_list.push({ pic_list: [], foot_list: [] ,description:""}))
// <div class="cover_show"></div>
const show_img = document.createElement('div');
show_img.className = 'step_show_all step_show_'+(num-1);
stepDiv.appendChild(show_img);
// 多图上传
const fileInput = document.createElement('button');
fileInput.textContent = '选择图片';
fileInput.onclick = function() {
open_img_chose('step_list',num-1);
};
stepDiv.appendChild(fileInput);
// 选择食材按钮
const selectIngredientButton = document.createElement('button');
selectIngredientButton.textContent = '选择食材';
selectIngredientButton.onclick = function() {
selectIngredient(stepDiv,num-1);
};
stepDiv.appendChild(selectIngredientButton);
// 步骤输入说明
const stepDescription = document.createElement('textarea');
stepDescription.placeholder = '步骤说明';
stepDescription.rows = 4;
stepDescription.cols = 50;
stepDescription.onblur = function() {
writeDescriptionChild(this,num-1);
};
stepDiv.appendChild(stepDescription);
// 每个步骤的 foot_list
const footList = document.createElement('div');
footList.className = 'foot_list';
stepDiv.appendChild(footList);
document.getElementById('box3_content').appendChild(stepDiv);
}
function selectIngredient(stepDiv,num) {
if (post_data.food_list.length === 0) {
alert('没有可用的食材');
return;
}
// 获取当前步骤的 foot_list
const footList = stepDiv.querySelector('.foot_list');
// 获取已经添加过的食材
const addedIngredients = Array.from(footList.getElementsByClassName('ingredient')).map(div => div.textContent);
// 过滤已经添加过的食材
const availableIngredients = post_data.food_list.filter(item => {
const ingredientText = `${item.name} ${item.weight}克`;
return !addedIngredients.includes(ingredientText);
});
if (availableIngredients.length === 0) {
alert('所有食材已添加');
return;
}
const randomIndex = Math.floor(Math.random() * availableIngredients.length);
const selectedIngredient = availableIngredients[randomIndex];
const ingredientDiv = document.createElement('div');
ingredientDiv.className = 'ingredient';
ingredientDiv.textContent = `${selectedIngredient.name} ${selectedIngredient.weight}克`;
const deleteButton = document.createElement('button');
deleteButton.textContent = '删除';
deleteButton.onclick = function() {
removeFootIngredient(ingredientDiv, selectedIngredient.name, selectedIngredient.weight, footList);
};
ingredientDiv.appendChild(deleteButton);
footList.appendChild(ingredientDiv);
// 添加数据进最终提交变量important
post_data.step_list[num]['foot_list'].push({name:selectedIngredient.name,weight:selectedIngredient.weight});
console.log(post_data)
}
function removeFootIngredient(divElement, ingredientName, ingredientWeight, footList) {
divElement.remove();
// 重新过滤 ingredientsList 以确保删除后不会重复添加
const addedIngredients = Array.from(footList.getElementsByClassName('ingredient')).map(div => div.textContent);
post_data.food_list = post_data.food_list.filter(item => {
const ingredientText = `${item.name} ${item.weight}克`;
return !addedIngredients.includes(ingredientText);
});
}
// 每个步骤的描述写入
function writeDescriptionChild(e,num){
// 添加数据进最终提交变量important
post_data.step_list[num]['description'] = $(e).val();
console.log(post_data)
}
function saveData() {
post_data.title = $("#title").val();
post_data.description = $("#description").val();
// 最终数据格式示意start
// post_data = {
// "cook_label": "早餐",
// "token": "asdasdasda123141321dfsd34123",
// "cover": "1",
// "title": "测试菜谱1",
// "description": "测试菜谱描述",
// "food_list": [
// {"name": " 牛肉","weight": "100"},
// {"name": " 鸡肉","weight": "200"},
// ...
// ],
// "step_list": [
// {
// "pic_list": [1,2],
// "foot_list": [
// {"name": " 牛肉","weight": "100"},
// ...
// ],
// "description": "步骤1说明"
// },
// ...
// ],
// };
// 最终数据格式示意end
console.log(post_data)
$.ajax({
url:"https://tc.pcxbc.com/kitchenscale/add_cookbook", //请求的url地址
// url:"http://wm.tcxbc.com/kitchenscale/add_cookbook", //请求的url地址
dataType:"json", //返回格式为json
async:true,//请求是否异步默认为异步这也是ajax重要特性
data:post_data, //参数值
type:"POST", //请求方式
success:function(req){
//请求成功时处理
if(req.code == 200){
alert("操作成功");
}else{
alert("操作失败");
}
},
error:function(){
//请求出错处理
}
});
}
</script>

View File

BIN
public/tsf/business_bg.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

18
vendor/autoload.php vendored
View File

@ -2,6 +2,24 @@
// autoload.php @generated by Composer
if (PHP_VERSION_ID < 50600) {
if (!headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
if (!ini_get('display_errors')) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, $err);
} elseif (!headers_sent()) {
echo $err;
}
}
trigger_error(
$err,
E_USER_ERROR
);
}
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit2bc4f313dba415539e266f7ac2c87dcd::getLoader();

View File

@ -37,26 +37,81 @@ namespace Composer\Autoload;
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be>
* @see http://www.php-fig.org/psr/psr-0/
* @see http://www.php-fig.org/psr/psr-4/
* @see https://www.php-fig.org/psr/psr-0/
* @see https://www.php-fig.org/psr/psr-4/
*/
class ClassLoader
{
/** @var \Closure(string):void */
private static $includeFile;
/** @var string|null */
private $vendorDir;
// PSR-4
/**
* @var array<string, array<string, int>>
*/
private $prefixLengthsPsr4 = array();
/**
* @var array<string, list<string>>
*/
private $prefixDirsPsr4 = array();
/**
* @var list<string>
*/
private $fallbackDirsPsr4 = array();
// PSR-0
/**
* List of PSR-0 prefixes
*
* Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2')))
*
* @var array<string, array<string, list<string>>>
*/
private $prefixesPsr0 = array();
/**
* @var list<string>
*/
private $fallbackDirsPsr0 = array();
/** @var bool */
private $useIncludePath = false;
/**
* @var array<string, string>
*/
private $classMap = array();
/** @var bool */
private $classMapAuthoritative = false;
/**
* @var array<string, bool>
*/
private $missingClasses = array();
/** @var string|null */
private $apcuPrefix;
/**
* @var array<string, self>
*/
private static $registeredLoaders = array();
/**
* @param string|null $vendorDir
*/
public function __construct($vendorDir = null)
{
$this->vendorDir = $vendorDir;
self::initializeIncludeClosure();
}
/**
* @return array<string, list<string>>
*/
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
@ -66,28 +121,42 @@ class ClassLoader
return array();
}
/**
* @return array<string, list<string>>
*/
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
/**
* @return list<string>
*/
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
/**
* @return list<string>
*/
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
/**
* @return array<string, string> Array of classname => path
*/
public function getClassMap()
{
return $this->classMap;
}
/**
* @param array $classMap Class to filename map
* @param array<string, string> $classMap Class to filename map
*
* @return void
*/
public function addClassMap(array $classMap)
{
@ -102,22 +171,25 @@ class ClassLoader
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
* @param string $prefix The prefix
* @param list<string>|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*
* @return void
*/
public function add($prefix, $paths, $prepend = false)
{
$paths = (array) $paths;
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
(array) $paths,
$paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
(array) $paths
$paths
);
}
@ -126,19 +198,19 @@ class ClassLoader
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
$this->prefixesPsr0[$first][$prefix] = $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
(array) $paths,
$paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
(array) $paths
$paths
);
}
}
@ -147,25 +219,28 @@ class ClassLoader
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param list<string>|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
$paths = (array) $paths;
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
(array) $paths,
$paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
(array) $paths
$paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
@ -175,18 +250,18 @@ class ClassLoader
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
$this->prefixDirsPsr4[$prefix] = $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
(array) $paths,
$paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
(array) $paths
$paths
);
}
}
@ -195,8 +270,10 @@ class ClassLoader
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 base directories
* @param string $prefix The prefix
* @param list<string>|string $paths The PSR-0 base directories
*
* @return void
*/
public function set($prefix, $paths)
{
@ -211,10 +288,12 @@ class ClassLoader
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param list<string>|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function setPsr4($prefix, $paths)
{
@ -234,6 +313,8 @@ class ClassLoader
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*
* @return void
*/
public function setUseIncludePath($useIncludePath)
{
@ -256,6 +337,8 @@ class ClassLoader
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
*
* @return void
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
@ -276,6 +359,8 @@ class ClassLoader
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
*
* @param string|null $apcuPrefix
*
* @return void
*/
public function setApcuPrefix($apcuPrefix)
{
@ -296,33 +381,55 @@ class ClassLoader
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*
* @return void
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
if (null === $this->vendorDir) {
return;
}
if ($prepend) {
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
} else {
unset(self::$registeredLoaders[$this->vendorDir]);
self::$registeredLoaders[$this->vendorDir] = $this;
}
}
/**
* Unregisters this instance as an autoloader.
*
* @return void
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
if (null !== $this->vendorDir) {
unset(self::$registeredLoaders[$this->vendorDir]);
}
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return bool|null True if loaded, null otherwise
* @return true|null True if loaded, null otherwise
*/
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
includeFile($file);
$includeFile = self::$includeFile;
$includeFile($file);
return true;
}
return null;
}
/**
@ -367,6 +474,21 @@ class ClassLoader
return $file;
}
/**
* Returns the currently registered loaders keyed by their corresponding vendor directories.
*
* @return array<string, self>
*/
public static function getRegisteredLoaders()
{
return self::$registeredLoaders;
}
/**
* @param string $class
* @param string $ext
* @return string|false
*/
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
@ -432,14 +554,26 @@ class ClassLoader
return false;
}
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*/
function includeFile($file)
{
include $file;
/**
* @return void
*/
private static function initializeIncludeClosure()
{
if (self::$includeFile !== null) {
return;
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*
* @param string $file
* @return void
*/
self::$includeFile = \Closure::bind(static function($file) {
include $file;
}, null, null);
}
}

362
vendor/composer/InstalledVersions.php vendored Normal file
View File

@ -0,0 +1,362 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer;
use Composer\Autoload\ClassLoader;
use Composer\Semver\VersionParser;
/**
* This class is copied in every Composer installed project and available to all
*
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
*
* To require its presence, you can require `composer-runtime-api ^2.0`
*
* @final
*/
class InstalledVersions
{
/**
* @var mixed[]|null
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
*/
private static $installed;
/**
* @var bool|null
*/
private static $canGetVendors;
/**
* @var array[]
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static $installedByVendor = array();
/**
* Returns a list of all package names which are present, either by being installed, replaced or provided
*
* @return string[]
* @psalm-return list<string>
*/
public static function getInstalledPackages()
{
$packages = array();
foreach (self::getInstalled() as $installed) {
$packages[] = array_keys($installed['versions']);
}
if (1 === \count($packages)) {
return $packages[0];
}
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
}
/**
* Returns a list of all package names with a specific type e.g. 'library'
*
* @param string $type
* @return string[]
* @psalm-return list<string>
*/
public static function getInstalledPackagesByType($type)
{
$packagesByType = array();
foreach (self::getInstalled() as $installed) {
foreach ($installed['versions'] as $name => $package) {
if (isset($package['type']) && $package['type'] === $type) {
$packagesByType[] = $name;
}
}
}
return $packagesByType;
}
/**
* Checks whether the given package is installed
*
* This also returns true if the package name is provided or replaced by another package
*
* @param string $packageName
* @param bool $includeDevRequirements
* @return bool
*/
public static function isInstalled($packageName, $includeDevRequirements = true)
{
foreach (self::getInstalled() as $installed) {
if (isset($installed['versions'][$packageName])) {
return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
}
}
return false;
}
/**
* Checks whether the given package satisfies a version constraint
*
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
*
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
*
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
* @param string $packageName
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
* @return bool
*/
public static function satisfies(VersionParser $parser, $packageName, $constraint)
{
$constraint = $parser->parseConstraints((string) $constraint);
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
return $provided->matches($constraint);
}
/**
* Returns a version constraint representing all the range(s) which are installed for a given package
*
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
* whether a given version of a package is installed, and not just whether it exists
*
* @param string $packageName
* @return string Version constraint usable with composer/semver
*/
public static function getVersionRanges($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
$ranges = array();
if (isset($installed['versions'][$packageName]['pretty_version'])) {
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
}
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
}
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
}
if (array_key_exists('provided', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
}
return implode(' || ', $ranges);
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
*/
public static function getVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['version'])) {
return null;
}
return $installed['versions'][$packageName]['version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
*/
public static function getPrettyVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
return null;
}
return $installed['versions'][$packageName]['pretty_version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
*/
public static function getReference($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['reference'])) {
return null;
}
return $installed['versions'][$packageName]['reference'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
*/
public static function getInstallPath($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @return array
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
*/
public static function getRootPackage()
{
$installed = self::getInstalled();
return $installed[0]['root'];
}
/**
* Returns the raw installed.php data for custom implementations
*
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
* @return array[]
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
*/
public static function getRawData()
{
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
if (null === self::$installed) {
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
self::$installed = include __DIR__ . '/installed.php';
} else {
self::$installed = array();
}
}
return self::$installed;
}
/**
* Returns the raw data of all installed.php which are currently loaded for custom implementations
*
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
public static function getAllRawData()
{
return self::getInstalled();
}
/**
* Lets you reload the static array from another file
*
* This is only useful for complex integrations in which a project needs to use
* this class but then also needs to execute another project's autoloader in process,
* and wants to ensure both projects have access to their version of installed.php.
*
* A typical case would be PHPUnit, where it would need to make sure it reads all
* the data it needs from this class, then call reload() with
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
* the project in which it runs can then also use this class safely, without
* interference between PHPUnit's dependencies and the project's dependencies.
*
* @param array[] $data A vendor/composer/installed.php data set
* @return void
*
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
*/
public static function reload($data)
{
self::$installed = $data;
self::$installedByVendor = array();
}
/**
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static function getInstalled()
{
if (null === self::$canGetVendors) {
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
}
$installed = array();
$copiedLocalDir = false;
if (self::$canGetVendors) {
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require $vendorDir.'/composer/installed.php';
self::$installedByVendor[$vendorDir] = $required;
$installed[] = $required;
if (strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
self::$installed = $required;
$copiedLocalDir = true;
}
}
}
}
if (null === self::$installed) {
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require __DIR__ . '/installed.php';
self::$installed = $required;
} else {
self::$installed = array();
}
}
if (self::$installed !== array() && !$copiedLocalDir) {
$installed[] = self::$installed;
}
return $installed;
}
}

View File

@ -2,9 +2,10 @@
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
'Stringable' => $vendorDir . '/myclabs/php-enum/stubs/Stringable.php',
);

View File

@ -2,7 +2,7 @@
// autoload_files.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(

View File

@ -2,7 +2,7 @@
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(

View File

@ -2,7 +2,7 @@
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(

View File

@ -22,52 +22,29 @@ class ComposerAutoloaderInit2bc4f313dba415539e266f7ac2c87dcd
return self::$loader;
}
require __DIR__ . '/platform_check.php';
spl_autoload_register(array('ComposerAutoloaderInit2bc4f313dba415539e266f7ac2c87dcd', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInit2bc4f313dba415539e266f7ac2c87dcd', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
require_once __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit2bc4f313dba415539e266f7ac2c87dcd::getInitializer($loader));
} else {
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}
$map = require __DIR__ . '/autoload_psr4.php';
foreach ($map as $namespace => $path) {
$loader->setPsr4($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
}
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit2bc4f313dba415539e266f7ac2c87dcd::getInitializer($loader));
$loader->register(true);
if ($useStaticLoader) {
$includeFiles = Composer\Autoload\ComposerStaticInit2bc4f313dba415539e266f7ac2c87dcd::$files;
} else {
$includeFiles = require __DIR__ . '/autoload_files.php';
}
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequire2bc4f313dba415539e266f7ac2c87dcd($fileIdentifier, $file);
$filesToLoad = \Composer\Autoload\ComposerStaticInit2bc4f313dba415539e266f7ac2c87dcd::$files;
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
require $file;
}
}, null, null);
foreach ($filesToLoad as $fileIdentifier => $file) {
$requireFile($fileIdentifier, $file);
}
return $loader;
}
}
function composerRequire2bc4f313dba415539e266f7ac2c87dcd($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
require $file;
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
}
}

View File

@ -115,6 +115,7 @@ class ComposerStaticInit2bc4f313dba415539e266f7ac2c87dcd
);
public static $classMap = array (
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
'Stringable' => __DIR__ . '/..' . '/myclabs/php-enum/stubs/Stringable.php',
);

File diff suppressed because it is too large Load Diff

149
vendor/composer/installed.php vendored Normal file
View File

@ -0,0 +1,149 @@
<?php return array(
'root' => array(
'name' => 'topthink/think',
'pretty_version' => 'dev-main',
'version' => 'dev-main',
'reference' => 'fcd7859cf4ed7d92ea7f2b5250e35e824d6b0d57',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'dev' => true,
),
'versions' => array(
'ezyang/htmlpurifier' => array(
'pretty_version' => 'v4.18.0',
'version' => '4.18.0.0',
'reference' => 'cb56001e54359df7ae76dc522d08845dc741621b',
'type' => 'library',
'install_path' => __DIR__ . '/../ezyang/htmlpurifier',
'aliases' => array(),
'dev_requirement' => false,
),
'maennchen/zipstream-php' => array(
'pretty_version' => '2.1.0',
'version' => '2.1.0.0',
'reference' => 'c4c5803cc1f93df3d2448478ef79394a5981cc58',
'type' => 'library',
'install_path' => __DIR__ . '/../maennchen/zipstream-php',
'aliases' => array(),
'dev_requirement' => false,
),
'markbaker/complex' => array(
'pretty_version' => '3.0.2',
'version' => '3.0.2.0',
'reference' => '95c56caa1cf5c766ad6d65b6344b807c1e8405b9',
'type' => 'library',
'install_path' => __DIR__ . '/../markbaker/complex',
'aliases' => array(),
'dev_requirement' => false,
),
'markbaker/matrix' => array(
'pretty_version' => '3.0.1',
'version' => '3.0.1.0',
'reference' => '728434227fe21be27ff6d86621a1b13107a2562c',
'type' => 'library',
'install_path' => __DIR__ . '/../markbaker/matrix',
'aliases' => array(),
'dev_requirement' => false,
),
'myclabs/php-enum' => array(
'pretty_version' => '1.8.4',
'version' => '1.8.4.0',
'reference' => 'a867478eae49c9f59ece437ae7f9506bfaa27483',
'type' => 'library',
'install_path' => __DIR__ . '/../myclabs/php-enum',
'aliases' => array(),
'dev_requirement' => false,
),
'phpmailer/phpmailer' => array(
'pretty_version' => 'v6.9.3',
'version' => '6.9.3.0',
'reference' => '2f5c94fe7493efc213f643c23b1b1c249d40f47e',
'type' => 'library',
'install_path' => __DIR__ . '/../phpmailer/phpmailer',
'aliases' => array(),
'dev_requirement' => false,
),
'phpoffice/phpspreadsheet' => array(
'pretty_version' => '1.25.2',
'version' => '1.25.2.0',
'reference' => 'a317a09e7def49852400a4b3eca4a4b0790ceeb5',
'type' => 'library',
'install_path' => __DIR__ . '/../phpoffice/phpspreadsheet',
'aliases' => array(),
'dev_requirement' => false,
),
'psr/http-client' => array(
'pretty_version' => '1.0.3',
'version' => '1.0.3.0',
'reference' => 'bb5906edc1c324c9a05aa0873d40117941e5fa90',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/http-client',
'aliases' => array(),
'dev_requirement' => false,
),
'psr/http-factory' => array(
'pretty_version' => '1.1.0',
'version' => '1.1.0.0',
'reference' => '2b4765fddfe3b508ac62f829e852b1501d3f6e8a',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/http-factory',
'aliases' => array(),
'dev_requirement' => false,
),
'psr/http-message' => array(
'pretty_version' => '1.1',
'version' => '1.1.0.0',
'reference' => 'cb6ce4845ce34a8ad9e68117c10ee90a29919eba',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/http-message',
'aliases' => array(),
'dev_requirement' => false,
),
'psr/simple-cache' => array(
'pretty_version' => '1.0.1',
'version' => '1.0.1.0',
'reference' => '408d5eafb83c57f6365a3ca330ff23aa4a5fa39b',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/simple-cache',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-mbstring' => array(
'pretty_version' => 'v1.31.0',
'version' => '1.31.0.0',
'reference' => '85181ba99b2345b0ef10ce42ecac37612d9fd341',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
'aliases' => array(),
'dev_requirement' => false,
),
'topthink/framework' => array(
'pretty_version' => 'v5.0.25',
'version' => '5.0.25.0',
'reference' => '643c58ed1bd22a2823ce5e95b3b68a5075f9087c',
'type' => 'think-framework',
'install_path' => __DIR__ . '/../../thinkphp',
'aliases' => array(),
'dev_requirement' => false,
),
'topthink/think' => array(
'pretty_version' => 'dev-main',
'version' => 'dev-main',
'reference' => 'fcd7859cf4ed7d92ea7f2b5250e35e824d6b0d57',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'dev_requirement' => false,
),
'topthink/think-installer' => array(
'pretty_version' => 'v1.0.14',
'version' => '1.0.14.0',
'reference' => 'eae1740ac264a55c06134b6685dfb9f837d004d1',
'type' => 'composer-plugin',
'install_path' => __DIR__ . '/../topthink/think-installer',
'aliases' => array(),
'dev_requirement' => false,
),
),
);

26
vendor/composer/platform_check.php vendored Normal file
View File

@ -0,0 +1,26 @@
<?php
// platform_check.php @generated by Composer
$issues = array();
if (!(PHP_VERSION_ID >= 70300)) {
$issues[] = 'Your Composer dependencies require a PHP version ">= 7.3.0". You are running ' . PHP_VERSION . '.';
}
if ($issues) {
if (!headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
if (!ini_get('display_errors')) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
} elseif (!headers_sent()) {
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
}
}
trigger_error(
'Composer detected issues in your platform: ' . implode(' ', $issues),
E_USER_ERROR
);
}

View File

@ -1 +1 @@
4.17.0
4.18.0

View File

@ -13,7 +13,7 @@
}
],
"require": {
"php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0"
"php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0"
},
"require-dev": {
"cerdic/css-tidy": "^1.7 || ^2.0",

View File

@ -7,7 +7,7 @@
* primary concern and you are using an opcode cache. PLEASE DO NOT EDIT THIS
* FILE, changes will be overwritten the next time the script is run.
*
* @version 4.17.0
* @version 4.18.0
*
* @warning
* You must *not* include any other HTML Purifier files before this file,
@ -101,6 +101,7 @@ require 'HTMLPurifier/AttrDef/CSS/Length.php';
require 'HTMLPurifier/AttrDef/CSS/ListStyle.php';
require 'HTMLPurifier/AttrDef/CSS/Multiple.php';
require 'HTMLPurifier/AttrDef/CSS/Percentage.php';
require 'HTMLPurifier/AttrDef/CSS/Ratio.php';
require 'HTMLPurifier/AttrDef/CSS/TextDecoration.php';
require 'HTMLPurifier/AttrDef/CSS/URI.php';
require 'HTMLPurifier/AttrDef/HTML/Bool.php';

View File

@ -19,7 +19,7 @@
*/
/*
HTML Purifier 4.17.0 - Standards Compliant HTML Filtering
HTML Purifier 4.18.0 - Standards Compliant HTML Filtering
Copyright (C) 2006-2008 Edward Z. Yang
This library is free software; you can redistribute it and/or
@ -58,12 +58,12 @@ class HTMLPurifier
* Version of HTML Purifier.
* @type string
*/
public $version = '4.17.0';
public $version = '4.18.0';
/**
* Constant with version of HTML Purifier.
*/
const VERSION = '4.17.0';
const VERSION = '4.18.0';
/**
* Global configuration object.

View File

@ -95,6 +95,7 @@ require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Length.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/ListStyle.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Multiple.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Percentage.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Ratio.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/TextDecoration.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/URI.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Bool.php';

View File

@ -27,6 +27,13 @@ class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef
$definition = $config->getCSSDefinition();
$allow_duplicates = $config->get("CSS.AllowDuplicates");
$universal_attrdef = new HTMLPurifier_AttrDef_Enum(
array(
'initial',
'inherit',
'unset',
)
);
// According to the CSS2.1 spec, the places where a
// non-delimiting semicolon can appear are in strings
@ -96,16 +103,13 @@ class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef
if (!$ok) {
continue;
}
// inefficient call, since the validator will do this again
if (strtolower(trim($value)) !== 'inherit') {
// inherit works for everything (but only on the base property)
$result = $universal_attrdef->validate($value, $config, $context);
if ($result === false) {
$result = $definition->info[$property]->validate(
$value,
$config,
$context
);
} else {
$result = 'inherit';
}
if ($result === false) {
continue;

View File

@ -0,0 +1,46 @@
<?php
/**
* Validates a ratio as defined by the CSS spec.
*/
class HTMLPurifier_AttrDef_CSS_Ratio extends HTMLPurifier_AttrDef
{
/**
* @param string $ratio Ratio to validate
* @param HTMLPurifier_Config $config Configuration options
* @param HTMLPurifier_Context $context Context
*
* @return string|boolean
*
* @warning Some contexts do not pass $config, $context. These
* variables should not be used without checking HTMLPurifier_Length
*/
public function validate($ratio, $config, $context)
{
$ratio = $this->parseCDATA($ratio);
$parts = explode('/', $ratio, 2);
$length = count($parts);
if ($length < 1 || $length > 2) {
return false;
}
$num = new \HTMLPurifier_AttrDef_CSS_Number();
if ($length === 1) {
return $num->validate($parts[0], $config, $context);
}
$num1 = $num->validate($parts[0], $config, $context);
$num2 = $num->validate($parts[1], $config, $context);
if ($num1 === false || $num2 === false) {
return false;
}
return $num1 . '/' . $num2;
}
}
// vim: et sw=4 sts=4

View File

@ -63,24 +63,18 @@ class HTMLPurifier_AttrDef_URI_Host extends HTMLPurifier_AttrDef
// This doesn't match I18N domain names, but we don't have proper IRI support,
// so force users to insert Punycode.
// There is not a good sense in which underscores should be
// allowed, since it's technically not! (And if you go as
// far to allow everything as specified by the DNS spec...
// well, that's literally everything, modulo some space limits
// for the components and the overall name (which, by the way,
// we are NOT checking!). So we (arbitrarily) decide this:
// let's allow underscores wherever we would have allowed
// hyphens, if they are enabled. This is a pretty good match
// for browser behavior, for example, a large number of browsers
// cannot handle foo_.example.com, but foo_bar.example.com is
// fairly well supported.
// Underscores defined as Unreserved Characters in RFC 3986 are
// allowed in a URI. There are cases where we want to consider a
// URI containing "_" such as "_dmarc.example.com".
// Underscores are not allowed in the default. If you want to
// allow it, set Core.AllowHostnameUnderscore to true.
$underscore = $config->get('Core.AllowHostnameUnderscore') ? '_' : '';
// Based off of RFC 1738, but amended so that
// as per RFC 3696, the top label need only not be all numeric.
// The productions describing this are:
$a = '[a-z]'; // alpha
$an = '[a-z0-9]'; // alphanum
$an = "[a-z0-9$underscore]"; // alphanum
$and = "[a-z0-9-$underscore]"; // alphanum | "-"
// domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
$domainlabel = "$an(?:$and*$an)?";

View File

@ -116,8 +116,6 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
'auto',
'cover',
'contain',
'initial',
'inherit',
]
),
new HTMLPurifier_AttrDef_CSS_Percentage(),
@ -236,21 +234,20 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
[
new HTMLPurifier_AttrDef_CSS_Length('0'),
new HTMLPurifier_AttrDef_CSS_Percentage(true),
new HTMLPurifier_AttrDef_Enum(['auto', 'initial', 'inherit'])
new HTMLPurifier_AttrDef_Enum(['auto'])
]
);
$trusted_min_wh = new HTMLPurifier_AttrDef_CSS_Composite(
[
new HTMLPurifier_AttrDef_CSS_Length('0'),
new HTMLPurifier_AttrDef_CSS_Percentage(true),
new HTMLPurifier_AttrDef_Enum(['initial', 'inherit'])
]
);
$trusted_max_wh = new HTMLPurifier_AttrDef_CSS_Composite(
[
new HTMLPurifier_AttrDef_CSS_Length('0'),
new HTMLPurifier_AttrDef_CSS_Percentage(true),
new HTMLPurifier_AttrDef_Enum(['none', 'initial', 'inherit'])
new HTMLPurifier_AttrDef_Enum(['none'])
]
);
$max = $config->get('CSS.MaxImgLength');
@ -278,12 +275,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
new HTMLPurifier_AttrDef_Switch(
'img',
// For img tags:
new HTMLPurifier_AttrDef_CSS_Composite(
[
new HTMLPurifier_AttrDef_CSS_Length('0', $max),
new HTMLPurifier_AttrDef_Enum(['initial', 'inherit'])
]
),
new HTMLPurifier_AttrDef_CSS_Length('0', $max),
// For everyone else:
$trusted_min_wh
);
@ -297,22 +289,29 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
new HTMLPurifier_AttrDef_CSS_Composite(
[
new HTMLPurifier_AttrDef_CSS_Length('0', $max),
new HTMLPurifier_AttrDef_Enum(['none', 'initial', 'inherit'])
new HTMLPurifier_AttrDef_Enum(['none'])
]
),
// For everyone else:
$trusted_max_wh
);
$this->info['aspect-ratio'] = new HTMLPurifier_AttrDef_CSS_Multiple(
new HTMLPurifier_AttrDef_CSS_Composite([
new HTMLPurifier_AttrDef_CSS_Ratio(),
new HTMLPurifier_AttrDef_Enum(['auto']),
])
);
// text-decoration and related shorthands
$this->info['text-decoration'] = new HTMLPurifier_AttrDef_CSS_TextDecoration();
$this->info['text-decoration-line'] = new HTMLPurifier_AttrDef_Enum(
['none', 'underline', 'overline', 'line-through', 'initial', 'inherit']
['none', 'underline', 'overline', 'line-through']
);
$this->info['text-decoration-style'] = new HTMLPurifier_AttrDef_Enum(
['solid', 'double', 'dotted', 'dashed', 'wavy', 'initial', 'inherit']
['solid', 'double', 'dotted', 'dashed', 'wavy']
);
$this->info['text-decoration-color'] = new HTMLPurifier_AttrDef_CSS_Color();
@ -320,7 +319,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
$this->info['text-decoration-thickness'] = new HTMLPurifier_AttrDef_CSS_Composite([
new HTMLPurifier_AttrDef_CSS_Length(),
new HTMLPurifier_AttrDef_CSS_Percentage(),
new HTMLPurifier_AttrDef_Enum(['auto', 'from-font', 'initial', 'inherit'])
new HTMLPurifier_AttrDef_Enum(['auto', 'from-font'])
]);
$this->info['font-family'] = new HTMLPurifier_AttrDef_CSS_FontFamily();

View File

@ -190,6 +190,9 @@ class HTMLPurifier_ChildDef_Table extends HTMLPurifier_ChildDef
$current_tr_tbody = null;
foreach($content as $node) {
if (!isset($node->name)) {
continue;
}
switch ($node->name) {
case 'tbody':
$current_tr_tbody = null;

View File

@ -21,7 +21,7 @@ class HTMLPurifier_Config
* HTML Purifier's version
* @type string
*/
public $version = '4.17.0';
public $version = '4.18.0';
/**
* Whether or not to automatically finalize

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,10 @@
Core.RemoveBlanks
TYPE: bool
DEFAULT: false
VERSION: 4.18
--DESCRIPTION--
<p>
If set to true, blank nodes will be removed. This can be useful for maintaining
backwards compatibility when upgrading from previous versions of PHP.
</p>
--# vim: et sw=4 sts=4

View File

@ -116,8 +116,8 @@ class HTMLPurifier_EntityParser
protected function entityCallback($matches)
{
$entity = $matches[0];
$hex_part = @$matches[1];
$dec_part = @$matches[2];
$hex_part = isset($matches[1]) ? $matches[1] : null;
$dec_part = isset($matches[2]) ? $matches[2] : null;
$named_part = empty($matches[3]) ? (empty($matches[4]) ? "" : $matches[4]) : $matches[3];
if ($hex_part !== NULL && $hex_part !== "") {
return HTMLPurifier_Encoder::unichr(hexdec($hex_part));

View File

@ -54,6 +54,11 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
*/
private $_enum_attrdef;
/**
* @type HTMLPurifier_AttrDef_Enum
*/
private $_universal_attrdef;
public function __construct()
{
$this->_tidy = new csstidy();
@ -70,6 +75,13 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
'focus'
)
);
$this->_universal_attrdef = new HTMLPurifier_AttrDef_Enum(
array(
'initial',
'inherit',
'unset',
)
);
}
/**
@ -307,6 +319,11 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
unset($style[$name]);
continue;
}
$uni_ret = $this->_universal_attrdef->validate($value, $config, $context);
if ($uni_ret !== false) {
$style[$name] = $uni_ret;
continue;
}
$def = $css_definition->info[$name];
$ret = $def->validate($value, $config, $context);
if ($ret === false) {

View File

@ -28,22 +28,28 @@ class HTMLPurifier_HTMLModule_Iframe extends HTMLPurifier_HTMLModule
if ($config->get('HTML.SafeIframe')) {
$this->safe = true;
}
$attrs = array(
'src' => 'URI#embedded',
'width' => 'Length',
'height' => 'Length',
'name' => 'ID',
'scrolling' => 'Enum#yes,no,auto',
'frameborder' => 'Enum#0,1',
'longdesc' => 'URI',
'marginheight' => 'Pixels',
'marginwidth' => 'Pixels',
);
if ($config->get('HTML.Trusted')) {
$attrs['allowfullscreen'] = 'Bool#allowfullscreen';
}
$this->addElement(
'iframe',
'Inline',
'Flow',
'Common',
array(
'src' => 'URI#embedded',
'width' => 'Length',
'height' => 'Length',
'name' => 'ID',
'scrolling' => 'Enum#yes,no,auto',
'frameborder' => 'Enum#0,1',
'longdesc' => 'URI',
'marginheight' => 'Pixels',
'marginwidth' => 'Pixels',
)
$attrs
);
}
}

View File

@ -269,20 +269,6 @@ class HTMLPurifier_Lexer
);
}
/**
* Special Internet Explorer conditional comments should be removed.
* @param string $string HTML string to process.
* @return string HTML with conditional comments removed.
*/
protected static function removeIEConditional($string)
{
return preg_replace(
'#<!--\[if [^>]+\]>.*?<!\[endif\]-->#si', // probably should generalize for all strings
'',
$string
);
}
/**
* Callback function for escapeCDATA() that does the work.
*
@ -323,8 +309,6 @@ class HTMLPurifier_Lexer
// escape CDATA
$html = $this->escapeCDATA($html);
$html = $this->removeIEConditional($html);
// extract body from document if applicable
if ($config->get('Core.ConvertDocumentToFragment')) {
$e = false;

View File

@ -72,6 +72,9 @@ class HTMLPurifier_Lexer_DOMLex extends HTMLPurifier_Lexer
if ($config->get('Core.AllowParseManyTags') && defined('LIBXML_PARSEHUGE')) {
$options |= LIBXML_PARSEHUGE;
}
if ($config->get('Core.RemoveBlanks') && defined('LIBXML_NOBLANKS')) {
$options |= LIBXML_NOBLANKS;
}
set_error_handler(array($this, 'muteErrorHandler'));
// loadHTML() fails on PHP 5.3 when second parameter is given

View File

@ -44,7 +44,7 @@ abstract class HTMLPurifier_Token_Tag extends HTMLPurifier_Token
$this->name = ctype_lower($name) ? $name : strtolower($name);
foreach ($attr as $key => $value) {
// normalization only necessary when key is not lowercase
if (!ctype_lower($key)) {
if (!ctype_lower((string)$key)) {
$new_key = strtolower($key);
if (!isset($attr[$new_key])) {
$attr[$new_key] = $attr[$key];

View File

@ -41,13 +41,13 @@ you should look at before rolling your own. Try [SwiftMailer](https://swiftmaile
, [Laminas/Mail](https://docs.laminas.dev/laminas-mail/), [ZetaComponents](https://github.com/zetacomponents/Mail), etc.
## License
This software is distributed under the [LGPL 2.1](http://www.gnu.org/licenses/lgpl-2.1.html) license, along with the [GPL Cooperation Commitment](https://gplcc.github.io/gplcc/). Please read [LICENSE](https://github.com/PHPMailer/PHPMailer/blob/master/LICENSE) for information on the software availability and distribution.
This software is distributed under the [LGPL 2.1](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html) license, along with the [GPL Cooperation Commitment](https://gplcc.github.io/gplcc/). Please read [LICENSE](https://github.com/PHPMailer/PHPMailer/blob/master/LICENSE) for information on the software availability and distribution.
## Installation & loading
PHPMailer is available on [Packagist](https://packagist.org/packages/phpmailer/phpmailer) (using semantic versioning), and installation via [Composer](https://getcomposer.org) is the recommended way to install PHPMailer. Just add this line to your `composer.json` file:
```json
"phpmailer/phpmailer": "^6.9.1"
"phpmailer/phpmailer": "^6.9.2"
```
or run
@ -144,7 +144,7 @@ If you are re-using the instance (e.g. when sending to a mailing list), you may
That's it. You should now be ready to use PHPMailer!
## Localization
PHPMailer defaults to English, but in the [language](https://github.com/PHPMailer/PHPMailer/tree/master/language/) folder, you'll find many translations for PHPMailer error messages that you may encounter. Their filenames contain [ISO 639-1](http://en.wikipedia.org/wiki/ISO_639-1) language code for the translations, for example `fr` for French. To specify a language, you need to tell PHPMailer which one to use, like this:
PHPMailer defaults to English, but in the [language](https://github.com/PHPMailer/PHPMailer/tree/master/language/) folder, you'll find many translations for PHPMailer error messages that you may encounter. Their filenames contain [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) language code for the translations, for example `fr` for French. To specify a language, you need to tell PHPMailer which one to use, like this:
```php
//To load the French version
@ -162,9 +162,9 @@ To reduce PHPMailer's deployed code footprint, examples are not included if you
Complete generated API documentation is [available online](https://phpmailer.github.io/PHPMailer/).
You can generate complete API-level documentation by running `phpdoc` in the top-level folder, and documentation will appear in the `docs` folder, though you'll need to have [PHPDocumentor](http://www.phpdoc.org) installed. You may find [the unit tests](https://github.com/PHPMailer/PHPMailer/blob/master/test/PHPMailerTest.php) a good reference for how to do various operations such as encryption.
You can generate complete API-level documentation by running `phpdoc` in the top-level folder, and documentation will appear in the `docs` folder, though you'll need to have [PHPDocumentor](https://www.phpdoc.org) installed. You may find [the unit tests](https://github.com/PHPMailer/PHPMailer/blob/master/test/PHPMailer/PHPMailerTest.php) a good reference for how to do various operations such as encryption.
If the documentation doesn't cover what you need, search the [many questions on Stack Overflow](http://stackoverflow.com/questions/tagged/phpmailer), and before you ask a question about "SMTP Error: Could not connect to SMTP host.", [read the troubleshooting guide](https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting).
If the documentation doesn't cover what you need, search the [many questions on Stack Overflow](https://stackoverflow.com/questions/tagged/phpmailer), and before you ask a question about "SMTP Error: Could not connect to SMTP host.", [read the troubleshooting guide](https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting).
## Tests
[PHPMailer tests](https://github.com/PHPMailer/PHPMailer/tree/master/test/) use PHPUnit 9, with [a polyfill](https://github.com/Yoast/PHPUnit-Polyfills) to let 9-style tests run on older PHPUnit and PHP versions.
@ -213,7 +213,7 @@ use. [Learn more.](https://tidelift.com/subscription/pkg/packagist-phpmailer-php
See [changelog](changelog.md).
## History
- PHPMailer was originally written in 2001 by Brent R. Matzelle as a [SourceForge project](http://sourceforge.net/projects/phpmailer/).
- PHPMailer was originally written in 2001 by Brent R. Matzelle as a [SourceForge project](https://sourceforge.net/projects/phpmailer/).
- [Marcus Bointon](https://github.com/Synchro) (`coolbru` on SF) and Andy Prevost (`codeworxtech`) took over the project in 2004.
- Became an Apache incubator project on Google Code in 2010, managed by Jim Jagielski.
- Marcus created [his fork on GitHub](https://github.com/Synchro/PHPMailer) in 2008.

View File

@ -13,13 +13,13 @@ PHPMailer versions 6.1.5 and earlier contain an output escaping bug that occurs
PHPMailer versions prior to 6.0.6 and 5.2.27 are vulnerable to an object injection attack by passing `phar://` paths into `addAttachment()` and other functions that may receive unfiltered local paths, possibly leading to RCE. Recorded as [CVE-2018-19296](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2018-19296). See [this article](https://knasmueller.net/5-answers-about-php-phar-exploitation) for more info on this type of vulnerability. Mitigated by blocking the use of paths containing URL-protocol style prefixes such as `phar://`. Reported by Sehun Oh of cyberone.kr.
PHPMailer versions prior to 5.2.24 (released July 26th 2017) have an XSS vulnerability in one of the code examples, [CVE-2017-11503](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2017-11503). The `code_generator.phps` example did not filter user input prior to output. This file is distributed with a `.phps` extension, so it it not normally executable unless it is explicitly renamed, and the file is not included when PHPMailer is loaded through composer, so it is safe by default. There was also an undisclosed potential XSS vulnerability in the default exception handler (unused by default). Patches for both issues kindly provided by Patrick Monnerat of the Fedora Project.
PHPMailer versions prior to 5.2.24 (released July 26th 2017) have an XSS vulnerability in one of the code examples, [CVE-2017-11503](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2017-11503). The `code_generator.phps` example did not filter user input prior to output. This file is distributed with a `.phps` extension, so it is not normally executable unless it is explicitly renamed, and the file is not included when PHPMailer is loaded through composer, so it is safe by default. There was also an undisclosed potential XSS vulnerability in the default exception handler (unused by default). Patches for both issues kindly provided by Patrick Monnerat of the Fedora Project.
PHPMailer versions prior to 5.2.22 (released January 9th 2017) have a local file disclosure vulnerability, [CVE-2017-5223](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2017-5223). If content passed into `msgHTML()` is sourced from unfiltered user input, relative paths can map to absolute local file paths and added as attachments. Also note that `addAttachment` (just like `file_get_contents`, `passthru`, `unlink`, etc) should not be passed user-sourced params either! Reported by Yongxiang Li of Asiasecurity.
PHPMailer versions prior to 5.2.20 (released December 28th 2016) are vulnerable to [CVE-2016-10045](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-10045) a remote code execution vulnerability, responsibly reported by [Dawid Golunski](https://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10045-Vuln-Patch-Bypass.html), and patched by Paul Buonopane (@Zenexer).
PHPMailer versions prior to 5.2.18 (released December 2016) are vulnerable to [CVE-2016-10033](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-10033) a remote code execution vulnerability, responsibly reported by [Dawid Golunski](http://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10033-Vuln.html).
PHPMailer versions prior to 5.2.18 (released December 2016) are vulnerable to [CVE-2016-10033](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-10033) a remote code execution vulnerability, responsibly reported by [Dawid Golunski](https://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10033-Vuln.html).
PHPMailer versions prior to 5.2.14 (released November 2015) are vulnerable to [CVE-2015-8476](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-8476) an SMTP CRLF injection bug permitting arbitrary message sending.

View File

@ -1 +1 @@
6.9.1
6.9.3

View File

@ -28,7 +28,8 @@
"config": {
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
}
},
"lock": false
},
"require": {
"php": ">=5.5.0",

View File

@ -12,7 +12,7 @@
* @copyright 2012 - 2020 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
@ -36,7 +36,7 @@ namespace PHPMailer\PHPMailer;
* Aliases for League Provider Classes
* Make sure you have added these to your composer.json and run `composer install`
* Plenty to choose from here:
* @see http://oauth2-client.thephpleague.com/providers/thirdparty/
* @see https://oauth2-client.thephpleague.com/providers/thirdparty/
*/
//@see https://github.com/thephpleague/oauth2-google
use League\OAuth2\Client\Provider\Google;
@ -178,5 +178,5 @@ if (!isset($_GET['code'])) {
);
//Use this to interact with an API on the users behalf
//Use this to get a new access token if the old one expires
echo 'Refresh Token: ', $token->getRefreshToken();
echo 'Refresh Token: ', htmlspecialchars($token->getRefreshToken());
}

View File

@ -5,27 +5,32 @@
* @package PHPMailer
* @author Matt Sturdy <matt.sturdy@gmail.com>
* @author Crystopher Glodzienski Cardoso <crystopher.glodzienski@gmail.com>
* @author Daniel Cruz <danicruz0415@gmail.com>
*/
$PHPMAILER_LANG['authenticate'] = 'Error SMTP: Imposible autentificar.';
$PHPMAILER_LANG['buggy_php'] = 'Tu versión de PHP está afectada por un bug que puede resultar en mensajes corruptos. Para arreglarlo, cambia a enviar usando SMTP, deshabilita la opción mail.add_x_header en tu php.ini, cambia a MacOS o Linux, o actualiza tu PHP a la versión 7.0.17+ o 7.1.3+.';
$PHPMAILER_LANG['connect_host'] = 'Error SMTP: Imposible conectar al servidor SMTP.';
$PHPMAILER_LANG['data_not_accepted'] = 'Error SMTP: Datos no aceptados.';
$PHPMAILER_LANG['empty_message'] = 'El cuerpo del mensaje está vacío.';
$PHPMAILER_LANG['encoding'] = 'Codificación desconocida: ';
$PHPMAILER_LANG['execute'] = 'Imposible ejecutar: ';
$PHPMAILER_LANG['extension_missing'] = 'Extensión faltante: ';
$PHPMAILER_LANG['file_access'] = 'Imposible acceder al archivo: ';
$PHPMAILER_LANG['file_open'] = 'Error de Archivo: Imposible abrir el archivo: ';
$PHPMAILER_LANG['from_failed'] = 'La(s) siguiente(s) direcciones de remitente fallaron: ';
$PHPMAILER_LANG['instantiate'] = 'Imposible crear una instancia de la función Mail.';
$PHPMAILER_LANG['invalid_address'] = 'Imposible enviar: dirección de email inválido: ';
$PHPMAILER_LANG['invalid_header'] = 'Nombre o valor de encabezado no válido';
$PHPMAILER_LANG['invalid_hostentry'] = 'Hostentry inválido: ';
$PHPMAILER_LANG['invalid_host'] = 'Host inválido: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' mailer no está soportado.';
$PHPMAILER_LANG['provide_address'] = 'Debe proporcionar al menos una dirección de email de destino.';
$PHPMAILER_LANG['recipients_failed'] = 'Error SMTP: Los siguientes destinos fallaron: ';
$PHPMAILER_LANG['signing'] = 'Error al firmar: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() falló.';
$PHPMAILER_LANG['smtp_error'] = 'Error del servidor SMTP: ';
$PHPMAILER_LANG['variable_set'] = 'No se pudo configurar la variable: ';
$PHPMAILER_LANG['extension_missing'] = 'Extensión faltante: ';
$PHPMAILER_LANG['smtp_code'] = 'Código del servidor SMTP: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'Información adicional del servidor SMTP: ';
$PHPMAILER_LANG['invalid_header'] = 'Nombre o valor de encabezado no válido';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() falló.';
$PHPMAILER_LANG['smtp_detail'] = 'Detalle: ';
$PHPMAILER_LANG['smtp_error'] = 'Error del servidor SMTP: ';
$PHPMAILER_LANG['variable_set'] = 'No se pudo configurar la variable: ';

View File

@ -6,7 +6,6 @@
* Some French punctuation requires a thin non-breaking space (U+202F) character before it,
* for example before a colon or exclamation mark.
* There is one of these characters between these quotes: ""
* @see http://unicode.org/udhr/n/notes_fra.html
*/
$PHPMAILER_LANG['authenticate'] = 'Erreur SMTP: échec de lauthentification.';
@ -31,7 +30,7 @@ $PHPMAILER_LANG['recipients_failed'] = 'Erreur SMTP:les destinataires s
$PHPMAILER_LANG['signing'] = 'Erreur de signature: ';
$PHPMAILER_LANG['smtp_code'] = 'Code SMTP: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'Informations supplémentaires SMTP: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'La fonction SMTP connect() a échouée.';
$PHPMAILER_LANG['smtp_connect_failed'] = 'La fonction SMTP connect() a échoué.';
$PHPMAILER_LANG['smtp_detail'] = 'Détails: ';
$PHPMAILER_LANG['smtp_error'] = 'Erreur du serveur SMTP: ';
$PHPMAILER_LANG['variable_set'] = 'Impossible dinitialiser ou de réinitialiser une variable: ';

View File

@ -3,27 +3,35 @@
/**
* Japanese PHPMailer language file: refer to English translation for definitive list
* @package PHPMailer
* @author Mitsuhiro Yoshida <http://mitstek.com/>
* @author Mitsuhiro Yoshida <https://mitstek.com>
* @author Yoshi Sakai <http://bluemooninc.jp/>
* @author Arisophy <https://github.com/arisophy/>
* @author ARAKI Musashi <https://github.com/arakim/>
*/
$PHPMAILER_LANG['authenticate'] = 'SMTPエラー: 認証できませんでした。';
$PHPMAILER_LANG['buggy_php'] = 'ご利用のバージョンのPHPには不具合があり、メッセージが破損するおそれがあります。問題の解決は以下のいずれかを行ってください。SMTPでの送信に切り替える。php.iniのmail.add_x_headerをoffにする。MacOSまたはLinuxに切り替える。PHPバージョン7.0.17以降または7.1.3以降にアップグレードする。';
$PHPMAILER_LANG['connect_host'] = 'SMTPエラー: SMTPホストに接続できませんでした。';
$PHPMAILER_LANG['data_not_accepted'] = 'SMTPエラー: データが受け付けられませんでした。';
$PHPMAILER_LANG['empty_message'] = 'メール本文が空です。';
$PHPMAILER_LANG['encoding'] = '不明なエンコーディング: ';
$PHPMAILER_LANG['execute'] = '実行できませんでした: ';
$PHPMAILER_LANG['extension_missing'] = '拡張機能が見つかりません: ';
$PHPMAILER_LANG['file_access'] = 'ファイルにアクセスできません: ';
$PHPMAILER_LANG['file_open'] = 'ファイルエラー: ファイルを開けません: ';
$PHPMAILER_LANG['from_failed'] = 'Fromアドレスを登録する際にエラーが発生しました: ';
$PHPMAILER_LANG['instantiate'] = 'メール関数が正常に動作しませんでした。';
$PHPMAILER_LANG['invalid_address'] = '不正なメールアドレス: ';
$PHPMAILER_LANG['provide_address'] = '少なくとも1つメールアドレスを 指定する必要があります。';
$PHPMAILER_LANG['invalid_header'] = '不正なヘッダー名またはその内容';
$PHPMAILER_LANG['invalid_hostentry'] = '不正なホストエントリー: ';
$PHPMAILER_LANG['invalid_host'] = '不正なホスト: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' メーラーがサポートされていません。';
$PHPMAILER_LANG['provide_address'] = '少なくとも1つメールアドレスを 指定する必要があります。';
$PHPMAILER_LANG['recipients_failed'] = 'SMTPエラー: 次の受信者アドレスに 間違いがあります: ';
$PHPMAILER_LANG['signing'] = '署名エラー: ';
$PHPMAILER_LANG['smtp_code'] = 'SMTPコード: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'SMTP追加情報: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP接続に失敗しました。';
$PHPMAILER_LANG['smtp_detail'] = '詳細: ';
$PHPMAILER_LANG['smtp_error'] = 'SMTPサーバーエラー: ';
$PHPMAILER_LANG['variable_set'] = '変数が存在しません: ';
$PHPMAILER_LANG['extension_missing'] = '拡張機能が見つかりません: ';

View File

@ -0,0 +1,27 @@
<?php
/**
* Kurdish (Sorani) PHPMailer language file: refer to English translation for definitive list
* @package PHPMailer
* @author Halo Salman <halo@home4t.com>
*/
$PHPMAILER_LANG['authenticate'] = 'هەڵەی SMTP : نەتوانرا کۆدەکە پشتڕاست بکرێتەوە ';
$PHPMAILER_LANG['connect_host'] = 'هەڵەی SMTP: نەتوانرا پەیوەندی بە سێرڤەرەوە بکات SMTP.';
$PHPMAILER_LANG['data_not_accepted'] = 'هەڵەی SMTP: ئەو زانیاریانە قبوڵ نەکرا.';
$PHPMAILER_LANG['empty_message'] = 'پەیامەکە بەتاڵە';
$PHPMAILER_LANG['encoding'] = 'کۆدکردنی نەزانراو : ';
$PHPMAILER_LANG['execute'] = 'ناتوانرێت جێبەجێ بکرێت: ';
$PHPMAILER_LANG['file_access'] = 'ناتوانرێت دەستت بگات بە فایلەکە: ';
$PHPMAILER_LANG['file_open'] = 'هەڵەی پەڕگە(فایل): ناتوانرێت بکرێتەوە: ';
$PHPMAILER_LANG['from_failed'] = 'هەڵە لە ئاستی ناونیشانی نێرەر: ';
$PHPMAILER_LANG['instantiate'] = 'ناتوانرێت خزمەتگوزاری پۆستە پێشکەش بکرێت.';
$PHPMAILER_LANG['invalid_address'] = 'نەتوانرا بنێردرێت ، چونکە ناونیشانی ئیمەیڵەکە نادروستە: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' مەیلەر پشتگیری ناکات';
$PHPMAILER_LANG['provide_address'] = 'دەبێت ناونیشانی ئیمەیڵی لانیکەم یەک وەرگر دابین بکرێت.';
$PHPMAILER_LANG['recipients_failed'] = ' هەڵەی SMTP: ئەم هەڵانەی خوارەوەشکستی هێنا لە ناردن بۆ هەردووکیان: ';
$PHPMAILER_LANG['signing'] = 'هەڵەی واژۆ: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect()پەیوەندی شکستی هێنا .';
$PHPMAILER_LANG['smtp_error'] = 'هەڵەی ئاستی سێرڤەری SMTP: ';
$PHPMAILER_LANG['variable_set'] = 'ناتوانرێت بیگۆڕیت یان دوبارە بینێریتەوە: ';
$PHPMAILER_LANG['extension_missing'] = 'درێژکراوە نەماوە: ';

View File

@ -5,24 +5,32 @@
* @package PHPMailer
* @author Alexey Chumakov <alex@chumakov.ru>
* @author Foster Snowhill <i18n@forstwoof.ru>
* @author ProjectSoft <projectsoft2009@yandex.ru>
*/
$PHPMAILER_LANG['authenticate'] = 'Ошибка SMTP: ошибка авторизации.';
$PHPMAILER_LANG['authenticate'] = 'Ошибка SMTP: не удалось пройти аутентификацию.';
$PHPMAILER_LANG['buggy_php'] = 'В вашей версии PHP есть ошибка, которая может привести к повреждению сообщений. Чтобы исправить, переключитесь на отправку по SMTP, отключите опцию mail.add_x_header в ваш php.ini, переключитесь на MacOS или Linux или обновите PHP до версии 7.0.17+ или 7.1.3+.';
$PHPMAILER_LANG['connect_host'] = 'Ошибка SMTP: не удается подключиться к SMTP-серверу.';
$PHPMAILER_LANG['data_not_accepted'] = 'Ошибка SMTP: данные не приняты.';
$PHPMAILER_LANG['empty_message'] = 'Пустое сообщение';
$PHPMAILER_LANG['encoding'] = 'Неизвестная кодировка: ';
$PHPMAILER_LANG['execute'] = 'Невозможно выполнить команду: ';
$PHPMAILER_LANG['extension_missing'] = 'Расширение отсутствует: ';
$PHPMAILER_LANG['file_access'] = 'Нет доступа к файлу: ';
$PHPMAILER_LANG['file_open'] = 'Файловая ошибка: не удаётся открыть файл: ';
$PHPMAILER_LANG['from_failed'] = 'Неверный адрес отправителя: ';
$PHPMAILER_LANG['instantiate'] = 'Невозможно запустить функцию mail().';
$PHPMAILER_LANG['provide_address'] = 'Пожалуйста, введите хотя бы один email-адрес получателя.';
$PHPMAILER_LANG['mailer_not_supported'] = ' — почтовый сервер не поддерживается.';
$PHPMAILER_LANG['recipients_failed'] = 'Ошибка SMTP: не удалась отправка таким адресатам: ';
$PHPMAILER_LANG['empty_message'] = 'Пустое сообщение';
$PHPMAILER_LANG['invalid_address'] = 'Не отправлено из-за неправильного формата email-адреса: ';
$PHPMAILER_LANG['invalid_header'] = 'Неверное имя или значение заголовка';
$PHPMAILER_LANG['invalid_hostentry'] = 'Неверная запись хоста: ';
$PHPMAILER_LANG['invalid_host'] = 'Неверный хост: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' — почтовый сервер не поддерживается.';
$PHPMAILER_LANG['provide_address'] = 'Вы должны указать хотя бы один адрес электронной почты получателя.';
$PHPMAILER_LANG['recipients_failed'] = 'Ошибка SMTP: Ошибка следующих получателей: ';
$PHPMAILER_LANG['signing'] = 'Ошибка подписи: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'Ошибка соединения с SMTP-сервером';
$PHPMAILER_LANG['smtp_code'] = 'Код SMTP: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'Дополнительная информация SMTP: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'Ошибка соединения с SMTP-сервером.';
$PHPMAILER_LANG['smtp_detail'] = 'Детали: ';
$PHPMAILER_LANG['smtp_error'] = 'Ошибка SMTP-сервера: ';
$PHPMAILER_LANG['variable_set'] = 'Невозможно установить или сбросить переменную: ';
$PHPMAILER_LANG['extension_missing'] = 'Расширение отсутствует: ';

View File

@ -11,21 +11,28 @@
*/
$PHPMAILER_LANG['authenticate'] = 'SMTP Hatası: Oturum açılamadı.';
$PHPMAILER_LANG['buggy_php'] = 'PHP sürümünüz iletilerin bozulmasına neden olabilecek bir hatadan etkileniyor. Bunu düzeltmek için, SMTP kullanarak göndermeye geçin, mail.add_x_header seçeneğini devre dışı bırakın php.ini dosyanızdaki mail.add_x_header seçeneğini devre dışı bırakın, MacOS veya Linux geçin veya PHP sürümünü 7.0.17+ veya 7.1.3+ sürümüne yükseltin,';
$PHPMAILER_LANG['connect_host'] = 'SMTP Hatası: SMTP sunucusuna bağlanılamadı.';
$PHPMAILER_LANG['data_not_accepted'] = 'SMTP Hatası: Veri kabul edilmedi.';
$PHPMAILER_LANG['empty_message'] = 'Mesajın içeriği boş';
$PHPMAILER_LANG['encoding'] = 'Bilinmeyen karakter kodlama: ';
$PHPMAILER_LANG['execute'] = 'Çalıştırılamadı: ';
$PHPMAILER_LANG['extension_missing'] = 'Eklenti bulunamadı: ';
$PHPMAILER_LANG['file_access'] = 'Dosyaya erişilemedi: ';
$PHPMAILER_LANG['file_open'] = 'Dosya Hatası: Dosya açılamadı: ';
$PHPMAILER_LANG['from_failed'] = 'Belirtilen adreslere gönderme başarısız: ';
$PHPMAILER_LANG['instantiate'] = 'Örnek e-posta fonksiyonu oluşturulamadı.';
$PHPMAILER_LANG['invalid_address'] = 'Geçersiz e-posta adresi: ';
$PHPMAILER_LANG['invalid_header'] = 'Geçersiz başlık adı veya değeri: ';
$PHPMAILER_LANG['invalid_hostentry'] = 'Geçersiz ana bilgisayar girişi: ';
$PHPMAILER_LANG['invalid_host'] = 'Geçersiz ana bilgisayar: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' e-posta kütüphanesi desteklenmiyor.';
$PHPMAILER_LANG['provide_address'] = 'En az bir alıcı e-posta adresi belirtmelisiniz.';
$PHPMAILER_LANG['recipients_failed'] = 'SMTP Hatası: Belirtilen alıcılara ulaşılamadı: ';
$PHPMAILER_LANG['signing'] = 'İmzalama hatası: ';
$PHPMAILER_LANG['smtp_code'] = 'SMTP kodu: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'ek SMTP bilgileri: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP connect() fonksiyonu başarısız.';
$PHPMAILER_LANG['smtp_detail'] = 'SMTP SMTP Detayı: ';
$PHPMAILER_LANG['smtp_error'] = 'SMTP sunucu hatası: ';
$PHPMAILER_LANG['variable_set'] = 'Değişken ayarlanamadı ya da sıfırlanamadı: ';
$PHPMAILER_LANG['extension_missing'] = 'Eklenti bulunamadı: ';

View File

@ -0,0 +1,30 @@
<?php
/**
* Urdu PHPMailer language file: refer to English translation for definitive list
* @package PHPMailer
* @author Saqib Ali Siddiqui <saqibsra@gmail.com>
*/
$PHPMAILER_LANG['authenticate'] = 'SMTP خرابی: تصدیق کرنے سے قاصر۔';
$PHPMAILER_LANG['connect_host'] = 'SMTP خرابی: سرور سے منسلک ہونے سے قاصر۔';
$PHPMAILER_LANG['data_not_accepted'] = 'SMTP خرابی: ڈیٹا قبول نہیں کیا گیا۔';
$PHPMAILER_LANG['empty_message'] = 'پیغام کی باڈی خالی ہے۔';
$PHPMAILER_LANG['encoding'] = 'نامعلوم انکوڈنگ: ';
$PHPMAILER_LANG['execute'] = 'عمل کرنے کے قابل نہیں ';
$PHPMAILER_LANG['file_access'] = 'فائل تک رسائی سے قاصر:';
$PHPMAILER_LANG['file_open'] = 'فائل کی خرابی: فائل کو کھولنے سے قاصر:';
$PHPMAILER_LANG['from_failed'] = 'درج ذیل بھیجنے والے کا پتہ ناکام ہو گیا:';
$PHPMAILER_LANG['instantiate'] = 'میل فنکشن کی مثال بنانے سے قاصر۔';
$PHPMAILER_LANG['invalid_address'] = 'بھیجنے سے قاصر: غلط ای میل پتہ:';
$PHPMAILER_LANG['mailer_not_supported'] = ' میلر تعاون یافتہ نہیں ہے۔';
$PHPMAILER_LANG['provide_address'] = 'آپ کو کم از کم ایک منزل کا ای میل پتہ فراہم کرنا چاہیے۔';
$PHPMAILER_LANG['recipients_failed'] = 'SMTP خرابی: درج ذیل پتہ پر نہیں بھیجا جاسکا: ';
$PHPMAILER_LANG['signing'] = 'دستخط کی خرابی: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP ملنا ناکام ہوا';
$PHPMAILER_LANG['smtp_error'] = 'SMTP سرور کی خرابی: ';
$PHPMAILER_LANG['variable_set'] = 'متغیر سیٹ نہیں کیا جا سکا: ';
$PHPMAILER_LANG['extension_missing'] = 'ایکٹینشن موجود نہیں ہے۔ ';
$PHPMAILER_LANG['smtp_code'] = 'SMTP سرور کوڈ: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'اضافی SMTP سرور کی معلومات:';
$PHPMAILER_LANG['invalid_header'] = 'غلط ہیڈر کا نام یا قدر';

View File

@ -13,7 +13,7 @@
* @copyright 2012 - 2023 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.

View File

@ -13,7 +13,7 @@
* @copyright 2012 - 2020 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.

View File

@ -13,7 +13,7 @@
* @copyright 2012 - 2020 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
@ -29,7 +29,7 @@ use League\OAuth2\Client\Token\AccessToken;
* OAuth - OAuth2 authentication wrapper class.
* Uses the oauth2-client package from the League of Extraordinary Packages.
*
* @see http://oauth2-client.thephpleague.com
* @see https://oauth2-client.thephpleague.com
*
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
*/

View File

@ -13,7 +13,7 @@
* @copyright 2012 - 2020 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.

View File

@ -13,7 +13,7 @@
* @copyright 2012 - 2020 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
@ -152,8 +152,7 @@ class PHPMailer
* Only supported in simple alt or alt_inline message types
* To generate iCal event structures, use classes like EasyPeasyICS or iCalcreator.
*
* @see http://sprain.ch/blog/downloads/php-class-easypeasyics-create-ical-files-with-php/
* @see http://kigkonsult.se/iCalcreator/
* @see https://kigkonsult.se/iCalcreator/
*
* @var string
*/
@ -254,7 +253,7 @@ class PHPMailer
* You can set your own, but it must be in the format "<id@domain>",
* as defined in RFC5322 section 3.6.4 or it will be ignored.
*
* @see https://tools.ietf.org/html/rfc5322#section-3.6.4
* @see https://www.rfc-editor.org/rfc/rfc5322#section-3.6.4
*
* @var string
*/
@ -358,7 +357,7 @@ class PHPMailer
public $AuthType = '';
/**
* SMTP SMTPXClient command attibutes
* SMTP SMTPXClient command attributes
*
* @var array
*/
@ -388,7 +387,7 @@ class PHPMailer
* 'DELAY' will notify you if there is an unusual delay in delivery, but the actual
* delivery's outcome (success or failure) is not yet decided.
*
* @see https://tools.ietf.org/html/rfc3461 See section 4.1 for more information about NOTIFY
* @see https://www.rfc-editor.org/rfc/rfc3461.html#section-4.1 for more information about NOTIFY
*/
public $dsn = '';
@ -468,7 +467,7 @@ class PHPMailer
* Only applicable when sending via SMTP.
*
* @see https://en.wikipedia.org/wiki/Variable_envelope_return_path
* @see http://www.postfix.org/VERP_README.html Postfix VERP info
* @see https://www.postfix.org/VERP_README.html Postfix VERP info
*
* @var bool
*/
@ -551,10 +550,10 @@ class PHPMailer
* The function that handles the result of the send email action.
* It is called out by send() for each email sent.
*
* Value can be any php callable: http://www.php.net/is_callable
* Value can be any php callable: https://www.php.net/is_callable
*
* Parameters:
* bool $result result of the send action
* bool $result result of the send action
* array $to email addresses of the recipients
* array $cc cc email addresses
* array $bcc bcc email addresses
@ -757,7 +756,7 @@ class PHPMailer
*
* @var string
*/
const VERSION = '6.9.1';
const VERSION = '6.9.3';
/**
* Error severity: message only, continue processing.
@ -903,7 +902,7 @@ class PHPMailer
}
//Is this a PSR-3 logger?
if ($this->Debugoutput instanceof \Psr\Log\LoggerInterface) {
$this->Debugoutput->debug($str);
$this->Debugoutput->debug(rtrim($str, "\r\n"));
return;
}
@ -1072,7 +1071,7 @@ class PHPMailer
* be modified after calling this function), addition of such addresses is delayed until send().
* Addresses that have been added already return false, but do not throw exceptions.
*
* @param string $kind One of 'to', 'cc', 'bcc', or 'ReplyTo'
* @param string $kind One of 'to', 'cc', 'bcc', or 'Reply-To'
* @param string $address The email address
* @param string $name An optional username associated with the address
*
@ -1212,7 +1211,7 @@ class PHPMailer
* Uses the imap_rfc822_parse_adrlist function if the IMAP extension is available.
* Note that quotes in the name part are removed.
*
* @see http://www.andrew.cmu.edu/user/agreen1/testing/mrbs/web/Mail/RFC822.php A more careful implementation
* @see https://www.andrew.cmu.edu/user/agreen1/testing/mrbs/web/Mail/RFC822.php A more careful implementation
*
* @param string $addrstr The address list string
* @param bool $useimap Whether to use the IMAP extension to parse the list
@ -1407,7 +1406,6 @@ class PHPMailer
* * IPv6 literals: 'first.last@[IPv6:a1::]'
* Not all of these will necessarily work for sending!
*
* @see http://squiloople.com/2009/12/20/email-address-validation/
* @copyright 2009-2010 Michael Rushton
* Feel free to use and redistribute this code. But please keep this copyright notice.
*/
@ -1734,9 +1732,8 @@ class PHPMailer
//This sets the SMTP envelope sender which gets turned into a return-path header by the receiver
//A space after `-f` is optional, but there is a long history of its presence
//causing problems, so we don't use one
//Exim docs: http://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html
//Sendmail docs: http://www.sendmail.org/~ca/email/man/sendmail.html
//Qmail docs: http://www.qmail.org/man/man8/qmail-inject.html
//Exim docs: https://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html
//Sendmail docs: https://www.sendmail.org/~ca/email/man/sendmail.html
//Example problem: https://www.drupal.org/node/1057954
//PHP 5.6 workaround
@ -1874,7 +1871,7 @@ class PHPMailer
*/
protected static function isPermittedPath($path)
{
//Matches scheme definition from https://tools.ietf.org/html/rfc3986#section-3.1
//Matches scheme definition from https://www.rfc-editor.org/rfc/rfc3986#section-3.1
return !preg_match('#^[a-z][a-z\d+.-]*://#i', $path);
}
@ -1901,7 +1898,7 @@ class PHPMailer
/**
* Send mail using the PHP mail() function.
*
* @see http://www.php.net/manual/en/book.mail.php
* @see https://www.php.net/manual/en/book.mail.php
*
* @param string $header The message headers
* @param string $body The message body
@ -1931,9 +1928,8 @@ class PHPMailer
//This sets the SMTP envelope sender which gets turned into a return-path header by the receiver
//A space after `-f` is optional, but there is a long history of its presence
//causing problems, so we don't use one
//Exim docs: http://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html
//Sendmail docs: http://www.sendmail.org/~ca/email/man/sendmail.html
//Qmail docs: http://www.qmail.org/man/man8/qmail-inject.html
//Exim docs: https://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html
//Sendmail docs: https://www.sendmail.org/~ca/email/man/sendmail.html
//Example problem: https://www.drupal.org/node/1057954
//CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped.
@ -2709,7 +2705,7 @@ class PHPMailer
}
//Only allow a custom message ID if it conforms to RFC 5322 section 3.6.4
//https://tools.ietf.org/html/rfc5322#section-3.6.4
//https://www.rfc-editor.org/rfc/rfc5322#section-3.6.4
if (
'' !== $this->MessageID &&
preg_match(
@ -3634,7 +3630,7 @@ class PHPMailer
* without breaking lines within a character.
* Adapted from a function by paravoid.
*
* @see http://www.php.net/manual/en/function.mb-encode-mimeheader.php#60283
* @see https://www.php.net/manual/en/function.mb-encode-mimeheader.php#60283
*
* @param string $str multi-byte text to wrap encode
* @param string $linebreak string to use as linefeed/end-of-line
@ -3690,7 +3686,7 @@ class PHPMailer
/**
* Encode a string using Q encoding.
*
* @see http://tools.ietf.org/html/rfc2047#section-4.2
* @see https://www.rfc-editor.org/rfc/rfc2047#section-4.2
*
* @param string $str the text to encode
* @param string $position Where the text is going to be used, see the RFC for what that means
@ -4228,7 +4224,7 @@ class PHPMailer
$result = $_SERVER['SERVER_NAME'];
} elseif (function_exists('gethostname') && gethostname() !== false) {
$result = gethostname();
} elseif (php_uname('n') !== false) {
} elseif (php_uname('n') !== '') {
$result = php_uname('n');
}
if (!static::isValidHost($result)) {
@ -4253,7 +4249,7 @@ class PHPMailer
empty($host)
|| !is_string($host)
|| strlen($host) > 256
|| !preg_match('/^([a-zA-Z\d.-]*|\[[a-fA-F\d:]+\])$/', $host)
|| !preg_match('/^([a-z\d.-]*|\[[a-f\d:]+\])$/i', $host)
) {
return false;
}
@ -4267,8 +4263,8 @@ class PHPMailer
//Is it a valid IPv4 address?
return filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false;
}
//Is it a syntactically valid hostname (when embeded in a URL)?
return filter_var('http://' . $host, FILTER_VALIDATE_URL) !== false;
//Is it a syntactically valid hostname (when embedded in a URL)?
return filter_var('https://' . $host, FILTER_VALIDATE_URL) !== false;
}
/**
@ -4679,7 +4675,7 @@ class PHPMailer
* Multi-byte-safe pathinfo replacement.
* Drop-in replacement for pathinfo(), but multibyte- and cross-platform-safe.
*
* @see http://www.php.net/manual/en/function.pathinfo.php#107461
* @see https://www.php.net/manual/en/function.pathinfo.php#107461
*
* @param string $path A filename or path, does not need to exist as a file
* @param int|string $options Either a PATHINFO_* constant,
@ -4914,7 +4910,7 @@ class PHPMailer
* Uses the 'relaxed' algorithm from RFC6376 section 3.4.2.
* Canonicalized headers should *always* use CRLF, regardless of mailer setting.
*
* @see https://tools.ietf.org/html/rfc6376#section-3.4.2
* @see https://www.rfc-editor.org/rfc/rfc6376#section-3.4.2
*
* @param string $signHeader Header
*
@ -4926,7 +4922,7 @@ class PHPMailer
$signHeader = static::normalizeBreaks($signHeader, self::CRLF);
//Unfold header lines
//Note PCRE \s is too broad a definition of whitespace; RFC5322 defines it as `[ \t]`
//@see https://tools.ietf.org/html/rfc5322#section-2.2
//@see https://www.rfc-editor.org/rfc/rfc5322#section-2.2
//That means this may break if you do something daft like put vertical tabs in your headers.
$signHeader = preg_replace('/\r\n[ \t]+/', ' ', $signHeader);
//Break headers out into an array
@ -4958,7 +4954,7 @@ class PHPMailer
* Uses the 'simple' algorithm from RFC6376 section 3.4.3.
* Canonicalized bodies should *always* use CRLF, regardless of mailer setting.
*
* @see https://tools.ietf.org/html/rfc6376#section-3.4.3
* @see https://www.rfc-editor.org/rfc/rfc6376#section-3.4.3
*
* @param string $body Message Body
*
@ -4994,7 +4990,7 @@ class PHPMailer
$DKIMquery = 'dns/txt'; //Query method
$DKIMtime = time();
//Always sign these headers without being asked
//Recommended list from https://tools.ietf.org/html/rfc6376#section-5.4.1
//Recommended list from https://www.rfc-editor.org/rfc/rfc6376#section-5.4.1
$autoSignHeaders = [
'from',
'to',
@ -5100,7 +5096,7 @@ class PHPMailer
}
//The DKIM-Signature header is included in the signature *except for* the value of the `b` tag
//which is appended after calculating the signature
//https://tools.ietf.org/html/rfc6376#section-3.5
//https://www.rfc-editor.org/rfc/rfc6376#section-3.5
$dkimSignatureHeader = 'DKIM-Signature: v=1;' .
' d=' . $this->DKIM_domain . ';' .
' s=' . $this->DKIM_selector . ';' . static::$LE .

View File

@ -13,7 +13,7 @@
* @copyright 2012 - 2020 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
@ -46,7 +46,7 @@ class POP3
*
* @var string
*/
const VERSION = '6.9.1';
const VERSION = '6.9.3';
/**
* Default POP3 port number.
@ -250,7 +250,9 @@ class POP3
//On Windows this will raise a PHP Warning error if the hostname doesn't exist.
//Rather than suppress it with @fsockopen, capture it cleanly instead
set_error_handler([$this, 'catchWarning']);
set_error_handler(function () {
call_user_func_array([$this, 'catchWarning'], func_get_args());
});
if (false === $port) {
$port = static::DEFAULT_PORT;

View File

@ -13,7 +13,7 @@
* @copyright 2012 - 2020 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
@ -35,7 +35,7 @@ class SMTP
*
* @var string
*/
const VERSION = '6.9.1';
const VERSION = '6.9.3';
/**
* SMTP line break constant.
@ -62,7 +62,7 @@ class SMTP
* The maximum line length allowed by RFC 5321 section 4.5.3.1.6,
* *excluding* a trailing CRLF break.
*
* @see https://tools.ietf.org/html/rfc5321#section-4.5.3.1.6
* @see https://www.rfc-editor.org/rfc/rfc5321#section-4.5.3.1.6
*
* @var int
*/
@ -72,7 +72,7 @@ class SMTP
* The maximum line length allowed for replies in RFC 5321 section 4.5.3.1.5,
* *including* a trailing CRLF line break.
*
* @see https://tools.ietf.org/html/rfc5321#section-4.5.3.1.5
* @see https://www.rfc-editor.org/rfc/rfc5321#section-4.5.3.1.5
*
* @var int
*/
@ -152,8 +152,8 @@ class SMTP
/**
* Whether to use VERP.
*
* @see http://en.wikipedia.org/wiki/Variable_envelope_return_path
* @see http://www.postfix.org/VERP_README.html Info on VERP
* @see https://en.wikipedia.org/wiki/Variable_envelope_return_path
* @see https://www.postfix.org/VERP_README.html Info on VERP
*
* @var bool
*/
@ -164,7 +164,7 @@ class SMTP
* Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2.
* This needs to be quite high to function correctly with hosts using greetdelay as an anti-spam measure.
*
* @see http://tools.ietf.org/html/rfc2821#section-4.5.3.2
* @see https://www.rfc-editor.org/rfc/rfc2821#section-4.5.3.2
*
* @var int
*/
@ -187,12 +187,12 @@ class SMTP
*/
protected $smtp_transaction_id_patterns = [
'exim' => '/[\d]{3} OK id=(.*)/',
'sendmail' => '/[\d]{3} 2.0.0 (.*) Message/',
'postfix' => '/[\d]{3} 2.0.0 Ok: queued as (.*)/',
'Microsoft_ESMTP' => '/[0-9]{3} 2.[\d].0 (.*)@(?:.*) Queued mail for delivery/',
'sendmail' => '/[\d]{3} 2\.0\.0 (.*) Message/',
'postfix' => '/[\d]{3} 2\.0\.0 Ok: queued as (.*)/',
'Microsoft_ESMTP' => '/[0-9]{3} 2\.[\d]\.0 (.*)@(?:.*) Queued mail for delivery/',
'Amazon_SES' => '/[\d]{3} Ok (.*)/',
'SendGrid' => '/[\d]{3} Ok: queued as (.*)/',
'CampaignMonitor' => '/[\d]{3} 2.0.0 OK:([a-zA-Z\d]{48})/',
'CampaignMonitor' => '/[\d]{3} 2\.0\.0 OK:([a-zA-Z\d]{48})/',
'Haraka' => '/[\d]{3} Message Queued \((.*)\)/',
'ZoneMTA' => '/[\d]{3} Message queued as (.*)/',
'Mailjet' => '/[\d]{3} OK queued as (.*)/',
@ -280,7 +280,8 @@ class SMTP
}
//Is this a PSR-3 logger?
if ($this->Debugoutput instanceof \Psr\Log\LoggerInterface) {
$this->Debugoutput->debug($str);
//Remove trailing line breaks potentially added by calls to SMTP::client_send()
$this->Debugoutput->debug(rtrim($str, "\r\n"));
return;
}
@ -293,6 +294,7 @@ class SMTP
switch ($this->Debugoutput) {
case 'error_log':
//Don't output, just log
/** @noinspection ForgottenDebugOutputInspection */
error_log($str);
break;
case 'html':
@ -371,7 +373,7 @@ class SMTP
}
//Anything other than a 220 response means something went wrong
//RFC 5321 says the server will wait for us to send a QUIT in response to a 554 error
//https://tools.ietf.org/html/rfc5321#section-3.1
//https://www.rfc-editor.org/rfc/rfc5321#section-3.1
if ($responseCode === 554) {
$this->quit();
}
@ -404,7 +406,9 @@ class SMTP
$errstr = '';
if ($streamok) {
$socket_context = stream_context_create($options);
set_error_handler([$this, 'errorHandler']);
set_error_handler(function () {
call_user_func_array([$this, 'errorHandler'], func_get_args());
});
$connection = stream_socket_client(
$host . ':' . $port,
$errno,
@ -419,7 +423,9 @@ class SMTP
'Connection: stream_socket_client not available, falling back to fsockopen',
self::DEBUG_CONNECTION
);
set_error_handler([$this, 'errorHandler']);
set_error_handler(function () {
call_user_func_array([$this, 'errorHandler'], func_get_args());
});
$connection = fsockopen(
$host,
$port,
@ -483,7 +489,9 @@ class SMTP
}
//Begin encrypted connection
set_error_handler([$this, 'errorHandler']);
set_error_handler(function () {
call_user_func_array([$this, 'errorHandler'], func_get_args());
});
$crypto_ok = stream_socket_enable_crypto(
$this->smtp_conn,
true,
@ -574,7 +582,7 @@ class SMTP
}
//Send encoded username and password
if (
//Format from https://tools.ietf.org/html/rfc4616#section-2
//Format from https://www.rfc-editor.org/rfc/rfc4616#section-2
//We skip the first field (it's forgery), so the string starts with a null byte
!$this->sendCommand(
'User & Password',
@ -648,7 +656,7 @@ class SMTP
}
//The following borrowed from
//http://php.net/manual/en/function.mhash.php#27225
//https://www.php.net/manual/en/function.mhash.php#27225
//RFC 2104 HMAC implementation for php.
//Creates an md5 HMAC.
@ -787,7 +795,7 @@ class SMTP
//Send the lines to the server
foreach ($lines_out as $line_out) {
//Dot-stuffing as per RFC5321 section 4.5.2
//https://tools.ietf.org/html/rfc5321#section-4.5.2
//https://www.rfc-editor.org/rfc/rfc5321#section-4.5.2
if (!empty($line_out) && $line_out[0] === '.') {
$line_out = '.' . $line_out;
}
@ -1162,7 +1170,9 @@ class SMTP
} else {
$this->edebug('CLIENT -> SERVER: ' . $data, self::DEBUG_CLIENT);
}
set_error_handler([$this, 'errorHandler']);
set_error_handler(function () {
call_user_func_array([$this, 'errorHandler'], func_get_args());
});
$result = fwrite($this->smtp_conn, $data);
restore_error_handler();
@ -1265,7 +1275,9 @@ class SMTP
while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) {
//Must pass vars in here as params are by reference
//solution for signals inspired by https://github.com/symfony/symfony/pull/6540
set_error_handler([$this, 'errorHandler']);
set_error_handler(function () {
call_user_func_array([$this, 'errorHandler'], func_get_args());
});
$n = stream_select($selR, $selW, $selW, $this->Timelimit);
restore_error_handler();

View File

@ -48,6 +48,11 @@ namespace Symfony\Polyfill\Mbstring;
* - mb_strstr - Finds first occurrence of a string within another
* - mb_strwidth - Return width of string
* - mb_substr_count - Count the number of substring occurrences
* - mb_ucfirst - Make a string's first character uppercase
* - mb_lcfirst - Make a string's first character lowercase
* - mb_trim - Strip whitespace (or other characters) from the beginning and end of a string
* - mb_ltrim - Strip whitespace (or other characters) from the beginning of a string
* - mb_rtrim - Strip whitespace (or other characters) from the end of a string
*
* Not implemented:
* - mb_convert_kana - Convert "kana" one from another ("zen-kaku", "han-kaku" and more)
@ -80,6 +85,15 @@ final class Mbstring
public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null)
{
if (\is_array($s)) {
$r = [];
foreach ($s as $str) {
$r[] = self::mb_convert_encoding($str, $toEncoding, $fromEncoding);
}
return $r;
}
if (\is_array($fromEncoding) || (null !== $fromEncoding && false !== strpos($fromEncoding, ','))) {
$fromEncoding = self::mb_detect_encoding($s, $fromEncoding);
} else {
@ -410,12 +424,6 @@ final class Mbstring
public static function mb_check_encoding($var = null, $encoding = null)
{
if (PHP_VERSION_ID < 70200 && \is_array($var)) {
trigger_error('mb_check_encoding() expects parameter 1 to be string, array given', \E_USER_WARNING);
return null;
}
if (null === $encoding) {
if (null === $var) {
return false;
@ -437,7 +445,6 @@ final class Mbstring
}
return true;
}
public static function mb_detect_encoding($str, $encodingList = null, $strict = false)
@ -827,7 +834,7 @@ final class Mbstring
return $code;
}
public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, string $encoding = null): string
public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, ?string $encoding = null): string
{
if (!\in_array($pad_type, [\STR_PAD_RIGHT, \STR_PAD_LEFT, \STR_PAD_BOTH], true)) {
throw new \ValueError('mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH');
@ -835,17 +842,8 @@ final class Mbstring
if (null === $encoding) {
$encoding = self::mb_internal_encoding();
}
try {
$validEncoding = @self::mb_check_encoding('', $encoding);
} catch (\ValueError $e) {
throw new \ValueError(sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding));
}
// BC for PHP 7.3 and lower
if (!$validEncoding) {
throw new \ValueError(sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding));
} else {
self::assertEncoding($encoding, 'mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given');
}
if (self::mb_strlen($pad_string, $encoding) <= 0) {
@ -871,6 +869,34 @@ final class Mbstring
}
}
public static function mb_ucfirst(string $string, ?string $encoding = null): string
{
if (null === $encoding) {
$encoding = self::mb_internal_encoding();
} else {
self::assertEncoding($encoding, 'mb_ucfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given');
}
$firstChar = mb_substr($string, 0, 1, $encoding);
$firstChar = mb_convert_case($firstChar, \MB_CASE_TITLE, $encoding);
return $firstChar.mb_substr($string, 1, null, $encoding);
}
public static function mb_lcfirst(string $string, ?string $encoding = null): string
{
if (null === $encoding) {
$encoding = self::mb_internal_encoding();
} else {
self::assertEncoding($encoding, 'mb_lcfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given');
}
$firstChar = mb_substr($string, 0, 1, $encoding);
$firstChar = mb_convert_case($firstChar, \MB_CASE_LOWER, $encoding);
return $firstChar.mb_substr($string, 1, null, $encoding);
}
private static function getSubpart($pos, $part, $haystack, $encoding)
{
if (false === $pos) {
@ -944,4 +970,76 @@ final class Mbstring
return $encoding;
}
public static function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string
{
return self::mb_internal_trim('{^[%s]+|[%1$s]+$}Du', $string, $characters, $encoding, __FUNCTION__);
}
public static function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string
{
return self::mb_internal_trim('{^[%s]+}Du', $string, $characters, $encoding, __FUNCTION__);
}
public static function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string
{
return self::mb_internal_trim('{[%s]+$}D', $string, $characters, $encoding, __FUNCTION__);
}
private static function mb_internal_trim(string $regex, string $string, ?string $characters, ?string $encoding, string $function): string
{
if (null === $encoding) {
$encoding = self::mb_internal_encoding();
} else {
self::assertEncoding($encoding, $function.'(): Argument #3 ($encoding) must be a valid encoding, "%s" given');
}
if ('' === $characters) {
return null === $encoding ? $string : self::mb_convert_encoding($string, $encoding);
}
if ('UTF-8' === $encoding) {
$encoding = null;
if (!preg_match('//u', $string)) {
$string = @iconv('UTF-8', 'UTF-8//IGNORE', $string);
}
if (null !== $characters && !preg_match('//u', $characters)) {
$characters = @iconv('UTF-8', 'UTF-8//IGNORE', $characters);
}
} else {
$string = iconv($encoding, 'UTF-8//IGNORE', $string);
if (null !== $characters) {
$characters = iconv($encoding, 'UTF-8//IGNORE', $characters);
}
}
if (null === $characters) {
$characters = "\\0 \f\n\r\t\v\u{00A0}\u{1680}\u{2000}\u{2001}\u{2002}\u{2003}\u{2004}\u{2005}\u{2006}\u{2007}\u{2008}\u{2009}\u{200A}\u{2028}\u{2029}\u{202F}\u{205F}\u{3000}\u{0085}\u{180E}";
} else {
$characters = preg_quote($characters);
}
$string = preg_replace(sprintf($regex, $characters), '', $string);
if (null === $encoding) {
return $string;
}
return iconv('UTF-8', $encoding.'//IGNORE', $string);
}
private static function assertEncoding(string $encoding, string $errorFormat): void
{
try {
$validEncoding = @self::mb_check_encoding('', $encoding);
} catch (\ValueError $e) {
throw new \ValueError(sprintf($errorFormat, $encoding));
}
// BC for PHP 7.3 and lower
if (!$validEncoding) {
throw new \ValueError(sprintf($errorFormat, $encoding));
}
}
}

Some files were not shown because too many files have changed in this diff Show More