学习总结
1.需要在腾讯云上购买并开通短信服务
2.需要下载证书到php的安装路径,证书文件cacert.pem
,更改php.ini
的配置文件curl.cainfo =C:\phpstudy_pro\Extensions\php\php7.3.4nts\cacert.pem
更改为证书的绝对路径
3.通过composer下载腾讯云短信包到laravel项目中composer require tencentcloud/tencentcloud-sdk-php
4.生成的验证码信息保存在Redis中
1.腾讯云平台短信服务中申请签名和短信模板
1.1发送短信需要的参数保存位置
2.前台登录控制器Account.php
<?php
namespace App\Http\Controllers\homes;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
//引入数据库查询构造器,链式调用
use Illuminate\Support\Facades\DB;
//手动验证用户名和密码
use Illuminate\Support\Facades\Auth;
//哈希密码加密
use Illuminate\Support\Facades\Hash;
//引入redis
use Illuminate\Support\Facades\Redis;
use Symfony\Component\VarDumper\VarDumper;
use TencentCloud\Common\Credential;
use TencentCloud\Common\Profile\ClientProfile;
use TencentCloud\Common\Profile\HttpProfile;
use TencentCloud\Common\Exception\TencentCloudSDKException;
use TencentCloud\Sms\V20190711\SmsClient;
use TencentCloud\Sms\V20190711\Models\SendSmsRequest;
//前台用户账号管理
class Account extends Controller
{
//前台用户登录界面
public function login()
{
return view('\homes\account\login');
}
//发送验证码短信
public function sendMessage(Request $req)
{
try {
//接收手机号码
$phone ='+86'.(string) $req->phone;
$redisCaptcha = Redis::get('login'.$phone);
//判断是否发送短信验证码
if(isset($redisCaptcha))
{
return json_encode(['code'=>0,'msg'=>'短信验证码已发送']);
}
//生成一个4位随机的验证码
$captcha =(string)rand(1000,9999);
//redis中短信验证码的存在时间
$existTime = '10';
$sec = (int)$existTime*60;
$cred = new Credential("SecretId", "SecretKey");
//存储在腾讯云->访问管理->访问密钥->API密钥管理中
$httpProfile = new HttpProfile();
$httpProfile->setEndpoint("sms.ap-beijing.tencentcloudapi.com");
$clientProfile = new ClientProfile();
$clientProfile->setHttpProfile($httpProfile);
$client = new SmsClient($cred, "ap-beijing", $clientProfile);
$reqSms = new SendSmsRequest();
$params = array(
"PhoneNumberSet" => array(
//要发送的手机号码
$phone
),
"TemplateID" => '模板ID',
//存储在腾讯云短信--国内短信--模板ID
"Sign" => '瑄然软件',
"TemplateParamSet" => array(
//要发送的验证码
$captcha,
//验证码几分钟内有效
$existTime,
),
"SessionContext" => 'angle',
"SmsSdkAppid" => 'SDKAppID'
//存储在腾讯云--短信--应用管理--应用列表中
);
$reqSms->fromJsonString(json_encode($params));
$resp = $client->SendSms($reqSms);
$resp = $resp->toJsonString();//回调信息是一个对象转换为json字符串
$resp = json_decode($resp,true);//json字符串转换为数组
$resp = $resp['SendStatusSet'][0];//获取状态信息
//var_dump($resp);
if(($resp['Code']=="Ok") && ($resp['Message']=="send success"))
{
//把手机号码和验证码存入redis服务器,存放时间为
Redis::setex('login'.$phone,$sec,$captcha);
return json_encode(['code'=>1,'msg'=>'发送成功']);
}
else
{
return json_encode(['code'=>0,'msg'=>$resp['Message']]);
}
//var_dump($resp);
//print_r($resp->toJsonString());
}
catch(TencentCloudSDKException $e) {
echo $e;
}
}
public function dologin(Request $req)
{
$phone ='+86'.$req->phone;
$captcha = $req->captcha;
$redisdata = Redis::get('login'.$phone);
$pwd = '123456';//初始化密码为123456
$secPwd =Hash::make($pwd);
if(isset($redisdata))
{
if($redisdata==$captcha)
{
$res = DB::table('member')->select('id')->where('phone',$phone)->item();
if($res)
{
DB::table('member')->where('id',$res['id'])->update(['lastlogin'=>time()]);
}
else
{
DB::table('member')->insert(['phone'=>$phone,'password'=>$secPwd,'reg_time'=>time()]);
}
//attempt方法使用比较密码时,密码不需要做哈希运算
$isLogin = Auth::guard('member')->attempt(['phone'=>$phone,'password'=>$pwd]);
if($isLogin)
{
return (json_encode(['code'=>1,'msg'=>'登录成功']));
}
else
{
exit(json_encode(['code'=>0,'msg'=>'登录失败']));
}
}
else
{
exit (json_encode(['code'=>0,'msg'=>'验证码错误']));
}
}
else
{
exit (json_encode(['code'=>0,'msg'=>'短信验证码过期,请重新发送验证码']));
}
}
}
3.前台登录页面 index.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="/static/plugins/layui/css/layui.css">
<script src="/static/plugins/layui/layui.js"></script>
<title>前台登录界面</title>
<style>
.layui-form{
padding: 15px;
margin-top: 30vh;
}
.get-captcha{
display: flex;
flex-flow: row nowrap;
}
/* 登录按钮 */
.login-btn{
/* border: 1px solid #000; */
width: 93vw;
text-align: center;
}
.login-btn>button{
width: 40vw;
}
</style>
</head>
<body>
<div class="main">
<div class="layui-form">
@csrf
{{-- 输入手机号码 --}}
<div class="layui-form-item">
<div class="layui-block">
<input class="layui-input" required lay-verify="required" type="text" name="phone" placeholder="请输入手机号码">
</div>
</div>
{{-- 获取短信验证码 --}}
<div class="layui-form-item get-captcha">
<div class="layui-inline">
<input type="text" class="layui-input" required lay-verify="required" name="captcha" style="width:35vw;" placeholder="请输入验证码">
</div>
<div class="layui-inline">
<button type="button" class="layui-btn layui-btn-primary" style="margin-left: 15px;" name="captchaBtn" onclick="getCaptcha()">获取验证码</button>
</div>
</div>
{{-- 登录 --}}
<div class="login-btn">
<button type="button" class="layui-btn layui-btn-warm layui-btn-radius" name="loginBtn" onclick="dologin()">登录</button>
</div>
</div>
</div>
</body>
<script>
layui.use(['layer'],function(){
$ = layui.jquery;
layer = layui.layer;
});
//发送短信验证码
function getCaptcha()
{
var phone = $('input[name="phone"]').val().trim();
if(checkPhone(phone))
{
$.get('/homes/account/sendMessage',
{
phone:phone
},
function(res){
res = JSON.parse(res);
// console.log(res);
if(res.code>0)
{
layer.msg('发送成功');
setTimeout(() => {
}, 1000);
}
else
{
layer.alert(res.msg,{icon:2});
}
});
}
}
//检测是否是有效的电话号码
function checkPhone(phone)
{
if(phone=="")
{
layer.alert("手机号码不能为空",{icon:2});
return false;
}
if(!(phone.match(/^1[34578]\d{9}$/)))
{
layer.alert("手机号码格式不正确",{icon:2});
return false;
}
return true;
}
//登录操作
function dologin()
{
var phone = $('input[name="phone"]').val().trim();
var captcha = $('input[name="captcha"]').val().trim();
var _token = $('input[name="_token"]').val();
$.post('/homes/account/dologin',
{
phone:phone,
captcha:captcha,
_token:_token,
},
function(res){
if(res.code>0)
{
layer.msg(res.msg);
setTimeout(() => {
window.location.href='/'
}, 1000);
}
else
{
layer.alert(res.msg,{icon:2});
}
}
,'json');
// console.log(phone,' ',captcha);
}
</script>
</html>
4.路由文件 web.php
<?php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function(){
return view('welcome');
});
//登录页面
Route::get('/admins/account/login','admins\Account@login')->name('login');//使用name()方法对路由进行命名
//验证码图片
Route::get('/admins/account/captcha','admins\Account@captcha');
//登录操作
Route::post('/admins/account/dologin','admins\Account@dologin');
//后台首页
//调用框架自带的auth中间件判断是否登录,namespace()方法指定控制器的命令空间,group()方法中是一个回调函数,把一组路由写在这个回调函数中
Route::namespace('admins')->middleware(['auth','rights'])->group(function(){
Route::get('/admins/home/index','Home@index');
Route::get('/admins/home/welcome','Home@welcome');
Route::get('/admins/home/logout','Home@logout');
//账号管理
Route::get('/admins/admin/index','Admin@index');
//添加账号
Route::get('/admins/admin/add','Admin@add');
//修改账号
Route::get('/admins/admin/edit','Admin@edit');
//保存账号
Route::post('/admins/admin/save','Admin@save');
//删除账号
Route::get('/admins/admin/del','Admin@del');
//菜单管理
Route::get('/admins/menus/index','Menus@index');
//添加菜单
Route::get('/admins/menus/add','Menus@add');
//修改菜单
Route::get('/admins/menus/edit','Menus@edit');
//保存菜单
Route::post('/admins/menus/save','Menus@save');
//删除菜单
Route::get('/admins/menus/del','Menus@del');
//角色管理
Route::get('/admins/groups/index','Groups@index');
//添加角色
Route::get('/admins/groups/add','Groups@add');
//修改角色
Route::get('/admins/groups/edit','Groups@edit');
//保存角色
Route::post('/admins/groups/save','Groups@save');
//删除角色
Route::get('/admins/groups/del','Groups@del');
//菜品管理
Route::get('/admins/dish/index','Dish@index');
Route::get('/admins/dish/add','Dish@add');
Route::post('/admins/dish/save','Dish@save');
Route::post('/admins/dish/del','Dish@del');
//菜品分类管理
Route::get('/admins/dish/cate','Dish@cate');
Route::get('/admins/dish/cate_add','Dish@cate_add');
Route::post('/admins/dish/cate_save','Dish@cate_save');
Route::post('/admins/dish/cate_del','Dish@cate_del');
//菜品制作方法
Route::get('/admins/dish/taste','Dish@taste');
Route::get('/admins/dish/taste_add','Dish@taste_add');
Route::post('/admins/dish/taste_save','Dish@taste_save');
Route::post('/admins/dish/taste_del','Dish@taste_del');
//菜品套餐管理
Route::get('/admins/dish/taocan','Dish@taocan');
Route::get('/admins/dish/taocan_add','Dish@taocan_add');
Route::get('/admins/dish/get_dish','Dish@get_dish');//动态取得某个菜类的数据,实现菜品选择框二级联动
Route::post('/admins/dish/taocan_save','Dish@taocan_save');
Route::post('/admins/dish/taocan_del','Dish@taocan_del');
//菜品套餐分组管理
Route::get('/admins/dish/group','Dish@group');
Route::get('/admins/dish/group_add','Dish@group_add');
Route::post('/admins/dish/group_save','Dish@group_save');
Route::post('/admins/dish/group_del','Dish@group_del');
//客服管理
//客服和客户聊天窗口
Route::get('/admins/servicer/index','Servicer@index');
//聊天消息保存
Route::get('/admins/servicer/save','Servicer@save');
//文件图片上传管理
//图片上传
Route::post('/admins/files/upload_img','Files@upload_img');
});
//前台登录
//向登录用户发送4位短信验证码
Route::get('/homes/account/sendMessage','homes\Account@sendMessage');
//前台用户登录界面
Route::get('/homes/account/login','homes\Account@login');
//前台用户登录操作
Route::post('/homes/account/dologin','homes\Account@dologin');
//前台
//调用框架自带的auth中间件判断是否登录,namespace()方法指定控制器的命令空间,group()方法中是一个回调函数,把一组路由写在这个回调函数中
Route::namespace('homes')->middleware('member')->group(function(){
//前台首页,点菜界面
Route::get('/','Home@index' );
//普通菜品的制作方法选择页面
Route::get('/dish_taste','Home@dish_taste');
//套餐菜品明细的选择
Route::get('/dish_taocan','Home@dish_taocan');
//第二份半价选择页面
Route::get('/dish_halfPrice','Home@dish_halfPrice');
//购物车
//购物车列表
Route::get('/homes/cart/index','Cart@index');
//获取购物车中的数据
Route::get('/homes/cart/backRedData','Cart@backRedData');
//购物车添加菜品
Route::post('/homes/cart/addDish','Cart@addDish');
//用户支付
Route::get('/homes/pay/wxPay','Pay@wxPay');
//微信支付回调
Route::get('/homes/pay/wxPayCallBack','Pay@wxPayCallBack');
});