参考博客 小程序授权登录并 laravel7(laravel8) token 应用 - 王越666 - 博客园

微信小程序sku商品规格选择器 - 简书

微信小程序 和 laravel8 实现搜索后分页 加载_guanj0623的博客-CSDN博客

https://www.jb51.net/article/207552.htm

.wxml(授权登录页面)

<!--前台页面,通过判断决定展示登录还是信息-->
<view wx:if="{{isHide}}"><view wx:if="{{canIUse}}" ><view class='header'><image src='/images/x.jpg'></image></view><view class='content'><view>申请获取以下权限</view><text>获得你的公开信息(昵称,头像等)</text></view><button type="primary"  open-type="getUserInfo" bind:tap="login">授权登录</button></view><view wx:else>请升级微信版本</view>
</view><view wx:else><view>我的首页内容</view>
</view>

.wxss(授权登录页面)

.header {margin: 90rpx 0 90rpx 50rpx;border-bottom: 1px solid #ccc;text-align: center;width: 650rpx;height: 300rpx;line-height: 450rpx;
}.header image {width: 200rpx;height: 200rpx;
}.content {margin-left: 50rpx;margin-bottom: 90rpx;
}.content text {display: block;color: #9d9d9d;margin-top: 40rpx;
}.bottom {border-radius: 80rpx;margin: 70rpx 50rpx;font-size: 35rpx;
}

.js(授权登录)

// index.js
// 获取应用实例
const app = getApp()Page({data: {canIUse: wx.canIUse('button.open-type.getUserInfo'),// 前台判断用的就是这个isHide: true},// 微信授权login(evt){var that=this;//    wx.getUserProfile获取用户信息wx.getUserProfile({// desc    声明获取用户个人信息后的用途,不超过30个字符desc: 'desc',success:res=>{if (res.userInfo) {/*  wx.login 调用接口获取登录凭证(code)。通过凭证进而换取用户登录态信息,包括用户在当前小程序的唯一标识(openid)、微信开放平台帐号下的唯一标识(unionid,若当前小程序已绑定到微信开放平台帐号)及本次登录的会话密钥(session_key)*/wx.login({success:ret=>{// 获取codevar code=ret.code;// 获取用户昵称var nickName=res.userInfo.nickName;// 获取用户照片var log=res.userInfo.avatarUrl;// 发送至php后端wx.request({url: 'http://www.yk.com/api/v1/wxlogin', //仅为示例,并非真实的接口地址data: {code:code,nickName:nickName,log:log},method:"POST",header: {'content-type': 'application/json' // 默认值},// 数据返回json格式success (res) {// 获取返回来的token,并将token进行保存至本地缓冲中wx.setStorageSync('token', res.data.data.token)// // 将用户id储存于本地wx.setStorageSync('userid', res.data.data.id);wx.reLaunch({url: '/pages/mine/mine',})}})}})}else{console.log('用户拒绝啦');}}})}
})

控制器

<?phpnamespace App\Http\Controllers\Api;use App\Http\Controllers\Controller;
use App\Models\User;
use App\Service\JwtServer;
use App\Service\Token;
use Illuminate\Http\Request;class LoginController extends Controller
{public function loginInfo(Request $request){//接收前台传来的值$params = $request->post();$code=$request->post('code');//获取appid$appID = "wx1378003a2bdb6c0c";// 从微信公众平台获得secret$appSecret = "37e8b20e2f4bb7e85707c92cc1f4f0e4";// 发送请求换取openid和sessionkey$url="https://api.weixin.qq.com/sns/jscode2session?appid=".$appID."&secret=".$appSecret."&js_code=".$code."&grant_type=authorization_code";// 暂使用file_get_contents()发送请求,你可以使用CURL扩展的形式实现,获取opid和session_key$res = json_decode(file_get_contents($url), true);//调用成功后定义一个新的数组,最主要的session_key和openid两个值$params['openid'] = $res['openid'];//  给$params追加session_key$params['session_key'] = $res['session_key'];//查看数据库里是否有openid,有就修改,没有就添加$res = User::where('openid', $params['openid'])->first();//用查找到的用户信息的id生成token$token=JwtServer::createToken($res['id']);//将token发送至小程序,小程序进行缓冲token和用户id$res['token']=$token;//有就修改用户的额openIDif ($res) {User::where('openid', $params['openid'])->update($params);return ['code' => 201, 'meg' => '修改成功', 'data' => $res];} else {//没有就添加新用户$add =User::create($params);return ['code' => 200, 'meg' => '添加成功', 'data' => $res];}}
}

App\Service新建Curl.php文件

<?phpnamespace App\Service;class Curl
{public static function getCurl($url){$headerArray =array("Content-type:application/json;","Accept:application/json");$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch,CURLOPT_HTTPHEADER,$headerArray);$output = curl_exec($ch);curl_close($ch);$output = json_decode($output,true);return $output;}}

composer 下载jwt

composer require firebase/php-jwt

service下建一个JwtServer.php,加人以下代码

App\Http\Middleware 下新建JwtToken.php 文件,toekn中间件

<?php
namespace App\Http\Middleware;
use App\Service\JwtServer;
use Closure;
use Illuminate\Http\Request;class JwtToken
{/*** Handle an incoming request.** @param  \Illuminate\Http\Request  $request* @param  \Closure  $next* @return mixed*/public function handle(Request $request, Closure $next){$token = $request->header('token');if(empty($token)){return response()->json(['code'=>40001,'msg'=>'请先登录','data'=>$token]);}$userId=JwtServer::decodeToken($token);if(!is_numeric($userId)){return response()->json(['code'=>40002,'msg'=>'token过期','data'=>$userId]);}$request['id'] = $userId;return $next($request);}
}

中间件kernel.php文件下

    protected $routeMiddleware = ['auth' => \App\Http\Middleware\Authenticate::class,'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,'can' => \Illuminate\Auth\Middleware\Authorize::class,'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
//        中间件'jwt'=>JwtToken::class];

定义api路由,注意api路由书写格式,默认api前缀

Route::group(['prefix'=>'v1','namespace'=>'Api'],function (){
//小程序登录Route::any('wxlogin','LoginController@loginInfo');
});Route::group(['middleware'=>'jwt','prefix'=>'v2','namespace'=>'Api'],function (){//获取手机验证码Route::get('phone','PhoneController@PhoneCode');//绑定手机Route::get('bound','PhoneController@bound');
//    查询商品列表Route::get('goods','IndexController@index');
//    获取商品详情Route::get('detail','IndexController@detail');
//    获取商品规格属性值Route::get('specs','IndexController@specs');//添加订单Route::post('orders','IndexController@orders');//获取订单详情Route::get('order','IndexController@order');//支付接口Route::post('pay','IndexController@pay');
});

手机发送验证码

.wxss(手机发送验证码)

<!--pages/logins/logins.wxml-->
<view class="container"><view class="title">绑定手机号</view><form catchsubmit="login"><view class="inputView"><input class="inputText" placeholder="请输入手机号" name="phone" bindinput="phone" /></view><view class="inputView"><input class="inputText" placeholder="请输入验证码" name="code" /><button class="line"  size="mini" bindtap="sendcode">{{codebtn}}</button></view><view class="loginBtnView"><button class="loginBtn" type="primary" formType="submit">绑定</button></view></form>
</view>

.wxss

.container { display: flex;  flex-direction: column; padding: 0; } .inputView { line-height: 45px; border-bottom:1px solid #999999;}
.title{width: 80%;font-weight: bold;font-size: 30px;
}.inputText { display: inline-block; line-height: 45px; padding-left: 10px; margin-top: 11px;color: #cccccc; font-size: 14px;} .line {border: 1px solid #ccc;border-radius: 20px; float: right; margin-top: 9px;color: #cccccc;} .loginBtn { margin-top: 40px; border-radius:10px;}

.js

// pages/logins/logins.js
Page({/*** 页面的初始数据*/data: {phone:'',code: '',codebtn:'发送验证码',disabled:false,},// 获取输入账号 phone: function (e) {let phone = e.detail.value;this.setData({phone: e.detail.value})},//发送验证码sendcode:function(){let that=this;let phone =this.data.phone;let token=wx.getStorageSync('token');// console.log(token)wx.request({url: 'http://www.yk.com/api/v2/phone', //仅为示例,并非真实的接口地址data: {phone},header: {token},method:"GET",success (res) {console.log(res.data)that.setData({code:res.data})}})},// 绑定处理login: function (evt) {// console.log(evt);var that = this;// console.log(this.data.code)var userid=wx.getStorageSync('userid')var token=wx.getStorageSync('token');wx.request({url: 'http://www.yk.com/api/v2/bound', // 仅为示例,并非真实的接口地址method: 'get',data: {phone: that.data.phone,code:that.data.code,userid:userid},header: {token},success(res) {if (res.data.code == "10000") {wx.reLaunch({url: '/pages/home/home',})} else {wx.showToast({title: res.data.msg,icon: 'none',duration: 2000})}}})}})

控制器

<?phpnamespace App\Http\Controllers\Api;use App\Http\Controllers\Controller;
use App\Models\User;use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;class PhoneController extends Controller
{/*** 获取验证码方法*  Request $request参数* $getphone 手机号 $code 验证码*/public function PhoneCode(Request $request){
//       接收手机号码$getPhone=$request->get('phone');//       生成一个随机四位的随机数$code=mt_rand(1111,9999);if(empty($getPhone) || empty($code)){return ['code'=>0,'data'=>'','msg'=>'参数不能为空'];}Cache::set($getPhone,$code,5000);
//
//        $statusStr = array(
//            "0" => "短信发送成功",
//            "-1" => "参数不全",
//            "-2" => "服务器空间不支持,请确认支持curl或者fsocket,联系您的空间商解决或者更换空间!",
//            "30" => "密码错误",
//            "40" => "账号不存在",
//            "41" => "余额不足",
//            "42" => "帐户已过期",
//            "43" => "IP地址限制",
//            "50" => "内容含有敏感词"
//        );
//        $smsapi = "http://api.smsbao.com/";
//        $user = "tannanping"; //短信平台帐号
//        $pass = md5(""); //短信平台密码
//        $content="短信内容".$code;//要发送的短信内容
//        $phone = $getPhone;//要发送短信的手机号码
//        $sendurl = $smsapi."sms?u=".$user."&p=".$pass."&m=".$phone."&c=".urlencode($content);
//        $result =file_get_contents($sendurl) ;
//       echo $statusStr[$result];return $code;}/*** 登录方法* 参数 Request $request*/public function bound(Request $request){$phone=$request->get('phone');$code=$request->get('code');//       取出缓存内的验证码$oldCode=Cache::get($phone);if($code!=$oldCode){return ['code'=>10001,'data'=>'','msg'=>'验证码不正确'];}else{$model=new User();$res=$model->where('phone',$phone)->first();if(empty($res)){return ['code'=>10002,'data'=>'','msg'=>'账号不存在'];}else{return ['code'=>10000,'data'=>$res,'msg'=>'绑定成功'];}}}}

app.js(先验证是否登录 判断token是否存在)

//app.js
App({onLaunch: function () {// 展示本地存储能力var logs = wx.getStorageSync('logs') || []logs.unshift(Date.now())wx.setStorageSync('logs', logs)var token=wx.getStorageSync('token');if(token!=""){wx.reLaunch({url: '/pages/mine/mine',})}else{wx.reLaunch({url: '/pages/index/index',})}// 登录wx.login({success: res => {// 发送 res.code 到后台换取 openId, sessionKey, unionId}})// 获取用户信息wx.getSetting({success: res => {if (res.authSetting['scope.userInfo']) {// 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框wx.getUserInfo({success: res => {// 可以将 res 发送给后台解码出 unionIdthis.globalData.userInfo = res.userInfo// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回// 所以此处加入 callback 以防止这种情况if (this.userInfoReadyCallback) {this.userInfoReadyCallback(res)}}})}}})},globalData: {userInfo: null}
})

控制器商品购物流程

<?phpnamespace App\Http\Controllers\Api;use App\Http\Controllers\Controller;
use App\Models\Goods;
use App\Models\Goodspecs;
use App\Models\Orders;
use App\Models\User;
use Illuminate\Http\Request;class IndexController extends Controller
{//展示商品列表数据public function index(Request $request){
//        $keyword = $request->input('keyword');$data = Goods::paginate(5);return ['status'=>200,'msg'=>'success','data'=>$data];}public function detail(Request $request){$id=$request->get('id');$model=new Goods();$res=$model->where('gid',$id)->first();return ['status'=>200,'msg'=>'success','data'=>$res];}public function specs(Request $request){$id=$request->get('id');$model=new Goods();$res=$model->where('gid',$id)->with(['specs','goodspecs'])->get();return ['status'=>200,'msg'=>'success','data'=>$res];}//添加订单public function orders(Request $request){$param=$request->post();//商品id$id=$request->post('g_id');//查询该商品的库存$good=new Goodspecs();$ku=$good->where('g_id',$id)->first();$number=$ku['num'];
//       判断商品库存是否足够if($number<$param['num']){return ['status'=>0,'msg'=>'商品库存不够','data'=>$number];}$model=new Orders();$res=$model->create($param);if(!$res){return ['status'=>0,'msg'=>'error','data'=>$res];}else{return ['status'=>200,'msg'=>'success','data'=>$res];}}//获取订单详情public function order(Request $request){$oid=$request->get('oid');$model=new Orders();$res=$model->where('oid',$oid)->with(['user','goods'])->get();return ['status'=>200,'msg'=>'success','data'=>$res];}
//    执行支付public function pay(Request $request){$oid=$request->post('oid');$uid=$request->post('uid');$model=new Orders();$oldprice=$model->where('oid',$oid)->first();$user=new User();$zh=$user->where('id',$uid)->first();if($zh['price']<$oldprice['price']){return ['status'=>0,'msg'=>'余额不足','data'=>$zh];}else{
//            商品属性表$goods=new Goodspecs();
//            获取原来库存$kc=$goods->where('g_id',$oldprice['g_id'])->first();//当前库存=原来库存-购买数量$newnumber=$kc['num']-$oldprice['num'];//支付成功 修改库存$res=$goods->where('g_id',$oldprice['g_id'])->update(['num'=>$newnumber]);}}}

商品列表

.wxml(商品列表)

<view><view><view><form bindsubmit="dopost"><view class="weui-search-bar"><view class="weui-search-bar__form"><!-- 搜索框 --><view class="weui-search-bar__box"><icon class="weui-icon-search_in-box" type="search" size="14"></icon><input type="text" name="keyword" value="{{keyword}}" class="weui-search-bar__input" placeholder="请输入搜索内容" /></view></view><!-- 搜索按钮,调用搜索查询方法 --><button size="mini" class="weui-search-bar__cancel-btn" form-type="submit">搜索</button></view></form></view></view><view class="page-section-spacing"><scroll-view scroll-y="true" class="page-scroll-style" bindscrolltolower="scroll"><block wx:for="{{activity}}" wx:key="activity"><view class="scroll-view-content"><image src="{{item.image}}" class="scroll-view-image" bindtap=""></image><view class="scroll-view-text" bindtap="detail" data-id="{{item.gid}}">{{item.name}}</view><view class="scroll-view-name">{{item.price}}</view></view></block></scroll-view></view>
</view>

.wxss

/**index.wxss**/
.weui-search-bar {position: relative;padding: 8px 10px;display: -webkit-box;display: -webkit-flex;display: flex;box-sizing: border-box;background-color: #EFEFF4;border-top: 1rpx solid #D7D6DC;border-bottom: 1rpx solid #D7D6DC;}.weui-icon-search_in-box {position: absolute;left: 10px;top: 7px;}.weui-search-bar__form {position: relative;-webkit-box-flex: 1;-webkit-flex: auto;flex: auto;border-radius: 5px;background: #FFFFFF;border: 1rpx solid #E6E6EA;}.weui-search-bar__box {position: relative;padding-left: 30px;padding-right: 30px;width: 100%;box-sizing: border-box;z-index: 1;}.weui-search-bar__input {height: 28px;line-height: 28px;font-size: 14px;}.weui-search-bar__cancel-btn {margin-left: 10px;line-height: 28px;color: #09BB07;white-space: nowrap;}.swp{height: 500rpx;}.page-section-spacing{margin-top: 60rpx;}.page-scroll-style{height: 1000rpx;background: aliceblue;}.scroll-view-content{height: 230rpx;margin: auto 10rpx;background: white;border: 1px solid gray;}.scroll-view-image{width: 200rpx;height: 200rpx;margin-top: 15rpx;margin-left: 20rpx;float: left;}.scroll-view-text{width: 400rpx;float: left;font-weight: 800;margin-top: 15rpx;margin-left: 20rpx;}.scroll-view-name{float: left;font-size: 30rpx;color: gray;margin-top: 20rpx;margin-left: 20rpx;}.scroll-view_H{white-space: nowrap;}.scroll-view-item{height: 300rpx;}.scroll-view-item_H{display: inline-block;width: 100%;height: 300rpx;}

.js

Page({/*** 页面的初始数据*/data: {activity:{},page:1,last_page : 0,keyword:''},detail:function(evn){let id=evn.target.dataset.id;wx.reLaunch({url: '/pages/detail/detail?id='+id,})},//加载scroll(e){let that = this;let page = that.data.page+1;let keyword = that.data.keywordthat.setData({page:page })let last_page = that.data.last_pageif(page > last_page){wx.showToast({title: '到底了',})return ;}wx.showLoading({title: '加载中',})let token=wx.getStorageSync('token');wx.request({url: 'http://www.yk.com/api/v2/goods',data:{page,keyword},header: {token},success (res) {console.log(res.data)let activity = res.data.data.datathat.setData({activity:that.data.activity.concat(activity),})wx.hideLoading()}})},/*** 生命周期函数--监听页面加载*/onLoad: function (options) {var that = this;let token=wx.getStorageSync('token');wx.request({url: 'http://www.yk.com/api/v2/goods',header: {token},success (res) {// console.log(res.data)let activity = res.data.data.datathat.setData({activity:activity,last_page:res.data.data.last_page,page:res.data.data.current_page})}})},//搜索dopost:function(e){console.log(e);let formData = e.detail.value;wx.request({url: 'http://www.week2.skill.com/api/activity/index',data:formData,method:"GET",success:res=>{console.log(res);if(res.data.status==200){this.setData({activity:res.data.data.data,keyword:formData.keyword,last_page:res.data.data.last_page,page:res.data.data.current_page})}},fail(e){wx.showToast({title: '请求失败',icon:"error"})}})},})

商品详情

.wxml

<!-- banner -->
<swiper indicator-dots="{{indicatorDots}}" autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}"><block><swiper-item><image src="{{activity.image}}" data-src="{{item}}" bindtap="previewImage"></image></swiper-item></block>
</swiper>
<scroll-view scroll-y="true"><view class="detail"><text class="title">{{activity.name}}</text><text class="price">¥{{activity.price}}</text></view><view class="separate"></view><!-- sku选择 --><text bindtap="toggleDialog">请选择购买数量</text><view class="separate"></view><text>商品评价</text><text class="text-remark">东西还可以,好评~</text><view class="separate"></view><text>商品详情</text><block wx:for-items="{{detailImg}}" wx:key="name"><image class="image_detail" src="{{item}}" /></block><view class="temp"></view>
</scroll-view>
<!-- 底部悬浮栏
<view class="detail-nav"><image bindtap="toCar"/><view class="line_nav"></view><image bindtap="addLike"/><button class="button-green" bindtap="addCar" formType="submit">加入购物车</button><button class="button-red" bindtap="immeBuy" formType="submit">立即购买</button>
</view> --><!--pages/demo/demo.wxml-->
<view class="container"><view class="footer-box" hover-class="btn-hover" bindtap="buy" data-id="{{activity.gid}}">立即购买</view><view class="mark" hidden='{{selHidden}}' bindtap='hiddenSel'></view><view class="detail-box" animation="{{animationDataSel}}" wx:for="{{activ}}"><view class="goods-img-box"><image src="{{item.image}}" class="goods-img"></image><view class='right-side'><view class='price'>¥{{item.price}}</view><view class='type'>已选:{{selTypeList}}</view><view class='inventory'>库存:{{activ.num}}</view></view><view class="sel-box"><view class="sel-list" wx:for="{{item.specs}}"><text class="{{indexArr[childIndex] == index ? 'active':''}}" bindtap="choice" data-fid="{{childIndex}}" data-id="{{index}}">{{item.name}}</text></view><view class="sel-list" wx:for="{{item.specs}}"><text class="{{indexArr[childIndex] == index ? 'active':''}}" bindtap="choice" data-fid="{{childIndex}}" data-id="{{index}}">{{item.name}}</text></view></view></view><view class="number-box" style="margin-top: 200px;"><view class="control {{plusBan}}" bindtap='plus'>+</view><view class="control num">{{selNum}}</view><view class="control {{minusBan}}" bindtap='minus'>-</view>  </view><view class="confirm-btn {{btnType}}"  bindtap='confirm' data-id="{{activity.gid}}" data-price="{{activity.price}}">确认</view></view>
</view>

.wxss

page {display: flex;flex-direction: column;height: 100%;}/* 直接设置swiper属性 */swiper {height: 500rpx;}swiper-item image {width: 100%;height: 100%;}.detail {display: flex;flex-direction: column;margin-top: 15rpx;margin-bottom: 0rpx;}.detail .title {font-size: 40rpx;margin: 10rpx;color: black;text-align: justify;}.detail .price {color: red;font-size: 40rpx;margin: 10rpx;}.line_flag {width: 80rpx;height: 1rpx;display: inline-block;margin: 20rpx auto;background-color: gainsboro;text-align: center;}.line {width: 100%;height: 2rpx;display: inline-block;margin: 20rpx 0rpx;background-color: gainsboro;text-align: center;}.detail-nav {display: flex;flex-direction: row;align-items: center;float: left;background-color: #fff;position: fixed;bottom: 0;right: 0;z-index: 1;width: 100%;height: 100rpx;}.button-green {background-color: #4caf50; /* Green */}.button-red {background-color: #f44336; /* 红色 */}.image_detail {width: 100%;}button {color: white;text-align: center;text-decoration: none;display: inline-block;font-size: 30rpx;border-radius: 0rpx;width: 50%;height: 100%;line-height: 100rpx;}.detail-nav image {width: 70rpx;height: 50rpx;margin: 20rpx 40rpx;}.line_nav {width: 5rpx;height: 100%;background-color: gainsboro;}/* 占位 */.temp {height: 100rpx;}text {display: block;height: 60rpx;line-height: 60rpx;font-size: 30rpx;margin: 10rpx;}.text-remark {display: block;font-size: 25rpx;margin: 10rpx;}/* pages/demo/demo.wxss */
.container .footer-box{position: fixed;bottom: 0rpx;margin: auto;height: 100rpx;width:100%;background-color: #E40112;text-align: center;line-height: 100rpx;color: #fff;font-size: 32rpx;
}
.container .btn-hover{opacity: 0.8;
}
.container .mark{position: fixed;z-index: 10;height: 100%;width: 100%;background-color: rgba(0, 0, 0, 0.75)
}
.container .detail-box{position: fixed;z-index: 10;bottom: -980rpx;height: 980rpx;width: 100%;background-color: #fff;
}
.container .detail-box .goods-img-box{height: 240rpx;box-sizing: border-box;padding: 24rpx;border-bottom: solid 1rpx #e3e3e3;
}
.container .detail-box .goods-img-box .goods-img{height: 192rpx;width: 192rpx;float: left;
}
.container .detail-box .goods-img-box .right-side{float: left;padding-top: 10rpx;
}
.container .detail-box .goods-img-box .right-side .price{font-size: 32rpx;color: #E40112;font-weight: bold;
}
.container .detail-box .goods-img-box .right-side .type{font-size: 24rpx;color: #333;margin-top: 8rpx;margin-bottom: 8rpx;overflow : hidden;text-overflow: ellipsis;display: -webkit-box;-webkit-line-clamp: 2;-webkit-box-orient: vertical;
}
.container .detail-box .goods-img-box .right-side .inventory{font-size: 24rpx;color: #999;
}.container .detail-box .sel-box{height: 560rpx;width: 100%;box-sizing: border-box;padding-bottom: 24rpx;overflow-y: auto;
}.container .detail-box .sel-box .sel-list .sel-title{font-size: 28rpx;color: #333;line-height: 60rpx;padding-left: 24rpx;
}
.container .detail-box .sel-box .sel-list .type-list{padding-left: 24rpx;
}
.container .detail-box .sel-box .sel-list .type-list {overflow: hidden;
}
.container .detail-box .sel-box .sel-list .type-list .type-item{display: inline-block;height: 50rpx;line-height: 48rpx;border: solid 1rpx #999;padding-left: 15rpx;padding-right: 15rpx;font-size: 24rpx;color: #666;border-radius: 5rpx;margin-right: 24rpx;margin-bottom: 24rpx;
}
.container .detail-box .sel-box .sel-list .type-list .sel{border: solid 1rpx #f63636;color: #f63636;
}
.container .detail-box .sel-box .sel-list .type-list .ban{background-color: #f5f5f5;border: solid 1rpx #f5f5f5;
}
.container .detail-box .confirm-btn{height: 100rpx;background-color: #E40112;text-align: center;line-height: 100rpx;color: #fff;font-size: 30rpx;
}
.container .detail-box .buy-ban{background-color: #ddd;
}
.container .detail-box .number-box{padding-left: 24rpx;padding-right: 24rpx;height: 80rpx;box-sizing: border-box;border-top: solid 1rpx #e3e3e3;
}
.container .detail-box .number-box .control{margin-top: 14rpx;float: right;height: 52rpx;width: 52rpx;background-color: #e3e3e3;text-align: center;line-height: 52rpx;color: #666;font-size: 36rpx;border-radius: 5rpx;margin-left: 4rpx;
}
.container .detail-box .number-box .ban{background-color: #F0F0F0;
}
.container .detail-box .number-box .num{width: 100rpx;font-size: 26rpx;background-color: #f0f0f0;font-family: Arial, Helvetica, sans-serif;
}

.js

Page({data: {shopping:[],selNum:1,//要购买的数量},minus:function(){//减少购买数量let that=this;if (that.data.minusBan=="ban"){return;}else{that.setData({selNum: that.data.selNum-1})if (that.data.selNum==1){that.setData({minusBan:"ban"})}}if (that.data.selNum == that.data.selStock) {that.setData({plusBan: "ban"})}else{that.setData({plusBan: ""})      }},plus:function(){//增加购买数量let that = this;if (that.data.plusBan == "ban"){return;}else{that.setData({selNum: that.data.selNum + 1})if (that.data.selNum == that.data.selStock) {that.setData({plusBan: "ban"})}if (that.data.selNum == 1) {that.setData({minusBan: "ban"})}else{that.setData({minusBan: ""})        }}},confirm:function(evn){//弹窗确认按钮触发let num=this.data.selNum;let u_id=wx.getStorageSync('userid');let g_id=evn.target.dataset.id;let oldprice=evn.target.dataset.price;//总价格=总数量*单价let price=num*oldprice;let token=wx.getStorageSync('token');wx.request({url: 'http://www.yk.com/api/v2/orders',method:'post',data:{u_id,g_id,num,price},header: {token},success (res) {// 获取订单idlet id=res.data.data.id;wx.reLaunch({url: '/pages/order/order?id='+id,})}})},onLoad: function (options) {//  商品idlet id=options.id;var that = this;let token=wx.getStorageSync('token');wx.request({url: 'http://www.yk.com/api/v2/detail',method:'GET',data:{id},header: {token},success (res) {// console.log(res.data)let activity = res.data.datathat.setData({activity:activity,})}})},buy:function(evn){// console.log(evn.target.dataset.id);// 商品idlet id=evn.target.dataset.id;//立即购买按钮触发this.showSelBox();let that = this;let token=wx.getStorageSync('token');wx.request({url: 'http://www.yk.com/api/v2/specs',method:'GET',data:{id},header: {token},success (res) {console.log(res.data.data)let activ = res.data.data;that.setData({activ:activ,})}})},onReady: function () {let that = thisthat.animation = wx.createAnimation({ //动画duration: 300, //动画持续时间timingFunction: 'linear', //动画的效果 动画从头到尾的速度是相同的transformOrigin: "50% 50% 0",})  },showSelBox: function (e) {//显示选项let that = this;let systemInfo = wx.getSystemInfoSync();let px = 980 / 750 * systemInfo.windowWidth;this.animation.translateY(-px).step() //在Y轴偏移tx,单位pxthis.setData({animationDataSel: that.animation.export(),selHidden: false,})},   })

订单页面

.wxml

<view wx:for="{{order}}" wx:key="order"><view wx:for="{{item.user}}"><view>{{item.nickName}}</view><view>{{item.phone}}</view></view><view style="margin-top: 100;" wx:for="{{item.goods}}"><view>{{item.name}}</view><image src="{{item.image}}"></image><view>单价{{item.price}}</view></view><view style="margin-top: 100;"><view>数量:{{item.num}}</view><view>总价:{{item.price}}</view><button bindtap="pay" data-id="{{item.oid}}">去支付</button></view></view>

.js

// pages/order/order.js
Page({/*** 页面的初始数据*/data: {},pay:function(evn){let oid=evn.target.dataset.id;let uid=wx.getStorageSync('userid');let token=wx.getStorageSync('token');wx.request({url: 'http://www.yk.com/api/v2/pay',method:'post',data:{oid,uid},header: {token},success (res) {// 获取订单idconsole.log(res)// let order=res.data.data;// console.log(order)// that.setData({//     order:order//   })// wx.reLaunch({//   url: '/pages/order/order?id='+id,// })}})},/*** 生命周期函数--监听页面加载*/onLoad: function (options) {let that=this;// console.log(options.id);let oid=options.id;let token=wx.getStorageSync('token');wx.request({url: 'http://www.yk.com/api/v2/order',method:'get',data:{oid},header: {token},success (res) {// 获取订单id// console.log(res)let order=res.data.data;console.log(order)that.setData({order:order})// wx.reLaunch({//   url: '/pages/order/order?id='+id,// })}})},/*** 生命周期函数--监听页面初次渲染完成*/onReady: function () {},/*** 生命周期函数--监听页面显示*/onShow: function () {},/*** 生命周期函数--监听页面隐藏*/onHide: function () {},/*** 生命周期函数--监听页面卸载*/onUnload: function () {},/*** 页面相关事件处理函数--监听用户下拉动作*/onPullDownRefresh: function () {},/*** 页面上拉触底事件的处理函数*/onReachBottom: function () {},/*** 用户点击右上角分享*/onShareAppMessage: function () {}
})

app.json

{"pages": ["pages/mine/mine","pages/index/index","pages/home/home","pages/detail/detail","pages/order/order"],"window": {"backgroundTextStyle": "light","navigationBarBackgroundColor": "#f0145a","navigationBarTitleText": "微商城","backgroundColor": "#f0145a"},"tabBar": {"color": "#858585","selectedColor": "#f0145a","backgroundColor": "#ffffff","borderStyle": "white","list": [{"pagePath": "pages/index/index","iconPath": "images/home.png","selectedIconPath": "images/home_select.png","text": "首页"},{"pagePath": "pages/home/home","iconPath": "images/classify.png","selectedIconPath": "images/classify_select.png","text": "分类"},{"pagePath": "pages/detail/detail","iconPath": "images/classify.png","selectedIconPath": "images/classify_select.png","text": "详情"},{"pagePath": "pages/mine/mine","iconPath": "images/mine.png","selectedIconPath": "images/mine_select.png","text": "我的"}]},"sitemapLocation": "sitemap.json"
}

微信小程序 授权登录+手机发送验证码+jwt验证接口(laravel8+php)相关推荐

  1. SpringBoot微信小程序授权登录

    SpringBoot微信小程序授权登录 一.appId 1.1.自己是管理者:微信公众平台,申请或登录自己的微信小程序,在开发者管理中即可看到 2.2.自己是开发者:让管理员将自己加入到小程序开发者管 ...

  2. 新版微信小程序授权登录流程及问题汇总(getUserProfile)

    问题来源:前不久去面试的时候有面试官问我你有自己的博客啥的吗?只能很尴尬的说没有.其实一直想有一个属于自己的博客啥的去记录自己在开发过程中遇到的问题,正好现在微信小程序比较流行,就花了两天自己搞了一个 ...

  3. SpringCloud 微信小程序授权登录 获取openId SessionKey【SpringCloud系列13】

    SpringCloud 大型系列课程正在制作中,欢迎大家关注与提意见. 自我提升方法推荐:神奇的早起 早上 5:00 -5:20 起床刷牙 5:30-6:00 晨练(跑步.跳绳.骑自行车.打球等等) ...

  4. 微信小程序授权登录第一次总是失败,第二次登录便正常了

    微信小程序授权登录第一次总是失败,第二次登录便正常了 错误流程 调用 用户点击授权用户信息按钮 ===> 调用wx.login( )生成code发送给后台生成session_key解密 ===& ...

  5. 微信小程序授权登录+获取手机号

    微信小程序授权登录+获取手机号 一.官方文档背景: 小程序登录的链接: 微信小程序获取手机号的链接: 二.微信小程序授权登录+获取手机号 1.简单说明官方文档的操作:先授权登录后拿手机号 2.前端代码 ...

  6. 微信小程序授权登录 组件的封装

    微信小程序授权登录 组件的封装 新建components文件 写wxml文件 wxss部分 js部分 json引用 页面使用 页面js 授权登录 流程如下: 因为多个页面功能需要登录状态 所以做了个组 ...

  7. uniapp微信小程序授权登录和获取微信绑定的手机号码

    uniapp微信小程序授权登录和获取微信绑定的手机号码 弹出授权的弹框 <view class="weixinOk" @tap="getUserProfile&qu ...

  8. 微信小程序授权登录取消授权重新授权处理方法 附可用代码

    微信小程序授权登录基本是小程序的标配了,但是官方的demo,取消授权后,就不能再重新点击登录,除非重新加载小程序才可以,这下怎么办? 我们可以先在首页引导用户点击,然后跳转到一个新的页面,在新的页面进 ...

  9. 微信小程序授权登录报错encryted_data或iv不合法,前端坑^-^~~

    微信小程序授权登录原来用的wx.getUserInfo(),在用户未授权过的情况下调用此接口,将不再出现授权弹窗, 会直接进入 fail 回调(详见<公告>).在用户已授权的情况下调用此接 ...

最新文章

  1. flask异步操作_Python Flask后端异步处理(三)
  2. Linux 中 7 个判断文件系统类型的方法
  3. 【JS】执行上下文(ExcecutionContext)
  4. 【详细注释】1051 Pop Sequence (25 分)
  5. hive查勘表结构_Hive中的数据库、表、数据与HDFS的对应关系
  6. spring(6) 渲染web视图
  7. NOIP模拟测试23「mine·water·gcd」
  8. 是什么决定了我们以何种方式赚钱?
  9. 【AI视野·今日Robot 机器人论文速览 第二十四期】Thu, 30 Sep 2021
  10. 漫步线性代数二十——快速傅里叶变换(下)
  11. matplotlib绘图_手把手教你使用Matplotlib绘图实战
  12. 基于JAVA+SpringBoot+Mybatis+MYSQL的汽车租赁系统
  13. Anroid开发中常用快捷键
  14. 两个组件对不齐(css样式问题)
  15. javaweb小区物业管理系统设计与实现(毕业论文+程序设计+数据库文件)
  16. 先选价、再叫车 高德打车首创上线“比价叫车”
  17. createBuilderConfig 0XFFFF异常
  18. buff系统 游戏中_原神buff状态有哪些 buff状态系统解析
  19. 图解机器学习-l2约束的最小二乘学习法-matlab源码
  20. 使用Python下载MP3

热门文章

  1. 音视频开发系列(27)AudioRecord录制PCM音频
  2. 全栈工程师到底有什么用?
  3. 盘古开源解读:我国大数据产业发展呈现出五大特点
  4. 数组某项抽离 + 数组去重
  5. 量化接口api是什么?
  6. python打蛇_hprose for java源码分析-1 初识
  7. 云计算机运行内存不足,电脑内存不足的九个解决办法
  8. 为什么RedisCluster会设计成16384个槽?
  9. mysql 如何自定义排序_在MySQL中实现自定义排序顺序
  10. Linux基础指令(覆盖80%)