在线看毛片视频-国产免费av在线-欧美日韩一区二区三区-国产成人无码av在线播放无广告-亚洲人va欧美va人人爽-国产第一草草-西班牙黄色片-四虎在线网站8848-最新av片免费网站入口-东京热无码中文字幕av专区-日本大人吃奶视频xxxx-欧美精品一区二区三区四区五区-国产片天天弄-国产免费内射又粗又爽密桃视频-欧美爱爱网站-日韩v欧美

當前位置:雨林木風下載站 > 網絡軟件教程 > 詳細頁面

微信硬件H5開發之控制燈光

微信硬件H5開發之控制燈光

更新時間:2025-09-20 文章作者:未知 信息來源:網絡 閱讀次數:

微信(WeChat)是騰訊公司于2011年1月21日推出的一個為智能終端提供即時通訊服務的免費應用程序,由張小龍所帶領的騰訊廣州研發中心產品團隊打造 [2] 。微信支持跨通信運營商、跨操作系統平臺...
微信(WeChat)是騰訊公司于2011年1月21日推出的一個為智能終端提供即時通訊服務的免費應用程序,由張小龍所帶領的騰訊廣州研發中心產品團隊打造 [2] 。微信支持跨通信運營商、跨操作系統平臺通過網絡快速發送免費(需消耗少量網絡流量)語音短信、視頻、圖片和文字,同時,也可以使用通過共享流媒體內容的資料和基于位置的社交插件“搖一搖”、“漂流瓶”、“朋友圈”、”公眾平臺“、”語音記事本“等服務插件。
這次給大家帶來微信硬件H5開發之控制燈光,微信硬件H5開發控制燈光的注意事項有哪些,下面就是實戰案例,一起來看一下。

你可以自己扒,帶參數的頁面在瀏覽器中打開會馬上跳轉,不帶參數的會提示參數不全,需要用mobile模式觀看。

呈現的界面如下:

微信硬件H5開發之控制燈光

目錄結構

解壓開lamp.js ,目錄如下,這個demo是基于sea.js+zepto實現,sea.js用來加載模塊,zepto提供ajax請求和tab事件等。

微信硬件H5開發之控制燈光

common中包含了一個keyConfig.js(地址參數),一個reqData.js(請求封裝)還有一個zepto,ui里是一個上面圖片的中的slider一樣的組件。util中是一組方法集合。最重要的就是lamp.js 。

define(function (require) {    var $ = require("common/zepto");    var keyConfig = require("common/keyConfig");    var reqData = require("common/reqData");    var util = require("util/util");    var ProcessBar = require("ui/process-bar");    var pageParam = {
        device_id: util.getQuery("device_id"),
        device_type: util.getQuery("device_type"),
        appid: util.getQuery("appid")
    };    var lastModTime = 0;    var powerBtn = $("#powerBtn"), // 開關按鈕        lightBar;    var device_status= {
        services: {
            lightbulb: {alpha:0},
            operation_status:{status:0}
        }
    }; // 數據對象
    (function () {        if(!pageParam.device_id || !pageParam.device_type){
            alert("頁面缺少參數");            return;
        }
        log("appid:" + pageParam.appid);
        log("device_id:" + pageParam.device_id);
        log("device_type:" + pageParam.device_type);
        powerBtn.on("tap", togglePower); // 開關按鈕事件        initBar();
        initInterval();        // todo : for test, delete before submit//        renderPage({});    })();    /**
     * 初始化進度條     */
    function initBar() {
        log("初始化lightBar");
        lightBar = new ProcessBar({
            $id: "lightBar",
            min: 0,
            stepCount: 100,
            step: 1,
            touchEnd: function (val) {
                device_status.services.lightbulb.alpha = val;
                log("亮度值為:"+val);                setData();
            }
        });
    }    /**
     * 請求數據     */
    function getData() {
        reqData.ajaxReq({            //url: keyConfig.GET_LAMP_STATUS,
            url:'https://api.weixin.qq.com/device/getlampstatus',
            data: pageParam,
            onSuccess: renderPage,
            onError:function(msg) {
                log("獲取數據失敗:" + JSON.stringify(msg));
            }
        });
    }    /**
     * 設置數據     */
    function setData() {
        console.log("setUrl", keyConfig.SET_LAMP_STATUS);
        lastModTime = new Date().getTime(); // 更新最后一次操作時間        reqData.ajaxReq({           // url: keyConfig.SET_LAMP_STATUS,
            url: 'https://api.weixin.qq.com/device/setlampstatus',
            type: "POST",
            data: JSON.stringify(device_status)
        });
        log("setData:" + JSON.stringify(device_status));
    }    /**
     * 開關按鈕事件     */
    function togglePower() {
        $("#switchBtn").toggleClass("on").toggleClass("off");
        log("燈的狀態status:"+device_status.services.operation_status.status);        if(device_status.services.operation_status.status==0){
            device_status.services.operation_status.status = 1;
            log("燈的狀態:1");
        } else {
            device_status.services.operation_status.status = 0;
            log("燈的狀態:0");
        }        setData();
    }    /**
     * 輪詢     */
    function initInterval() {
        getData();
        setInterval(function () {            if((new Date().getTime() - lastModTime) > 2000){ // 當有設置操作時,停止1s輪詢,2秒后繼續輪詢                getData();
            }
        }, 1000);
    }    /**
     * 渲染頁面     */
    function renderPage(json) {        // todo : for test, delete before submit//        json = {//            device_status: {//                services: {//                    operation_status: {//                        status: 0//                    },//                    lightbulb: {//                        alpha: 0//                    }//                }//            }//        };
        log("renderPage:"+json);        if(!json.device_status){            return;
        }
        console.log("json", json);
        device_status = json.device_status;
        log(device_status);        if(device_status.services.operation_status.status==0){
            $("#switchBtn").addClass("on").removeClass("off");
        } else {
            $("#switchBtn").addClass("off").removeClass("on");
        }
        lightBar.setVal(device_status.services.lightbulb.alpha);
    }
});/*  |xGv00|4199711a9ade00e2807e7ea576d92f55 */

首先我們看到pageParam對象是獲取頁面上參數的,device_id,device_type以及appid三個參數。其實有用的只有前面兩個,因為appid的話,后臺服務器已經配置了,而且在微信中的通過“進入面板”的時候只附帶了id和type兩個參數。然后device_status是一個設備狀態對象對象是燈,根據微信services的定義,燈有一個亮度值。這個在上一篇提到過。然后是一個立即執行的匿名函數,這個函數函數里面會先檢查一下參數,然后初始化開關和亮度條。最好進入循環。initInterval中就是不斷的通過getdata獲取數據。注意到這兒有一個lastModTime的比較,然后延時2秒再觸發,這個地方主要是因為每次設置之后再從服務器撈到數據有一個延時。原本是10,你設置了20,bar也到了20的位置,但是呢,服務器還有一個10在路上發過來,你設置的20并沒有馬上失效,這會有一個卡頓的效果。但這個兩秒也不是那么的有效,卡頓還是會有;另外一方面就是,不能設置太快,設置太快了會報50019的錯誤(設備正在被操作);getdata成功后,就是renderpage,這個不用解釋了。注意到在綁定開關時間的地方,其實是先調用了一次setdata

 powerBtn.on("tap", togglePower); function togglePower() {
        $("#switchBtn").toggleClass("on").toggleClass("off");
        log("燈的狀態status:"+device_status.services.operation_status.status);        if(device_status.services.operation_status.status==0){
            device_status.services.operation_status.status = 1;
            log("燈的狀態:1");
        } else {
            device_status.services.operation_status.status = 0;
            log("燈的狀態:0");
        }        setData();
    }

這個作用有兩個,一個是獲取設備目前的狀態,因為設備可能沒有開啟,或者沒有聯網,二個是將參數傳遞給后臺,不然getdata無效。最后理清一下思路就是

獲取參數-->初始化-->setdata一次-->循環-->渲染頁面 界面操作-->setdata-->延時讀取。 加上后端的部分,全部的流程圖如下。

微信硬件H5開發之控制燈光

所以拿到前端代碼只是一半,后端還需要自己實現。

實現

純靜態文件是無法請求微信服務器的,所以我們需要自己實現后臺的部分,這也是第一節中要講的目的。

html:

@{
    Layout = null;
}<!DOCTYPE html><html><head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta id="viewport" name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
    <title>我的燈泡</title>
    <link href="/css/common.css" rel="stylesheet" />
    <link href="/css/light_switch.css" rel="stylesheet" /></head><body>
    <p>
        <p class="body">
            <p class="inner">
                <p id="switchBtn" class="status_button off">
                    <p class="button_wrp">
                        <p class="button_mask">
                            <p class="alerter_button" id="powerBtn">
                                <i class="status_pot"></i>
                                <span class="on">ON</span>
                                <span class="off">OFF</span>
                            </p>
                        </p>
                    </p>
                    <p class="on">
                        <h2>燈已開</h2>
                    </p>
                </p>
                <p id="reData"></p>
            </p>
        </p>
        <p class="foot">
            <p class="slider_box J_slider_box">
                <i class="slider_box_icon icon dark"></i>
                <p id="lightBar" class="slider_box_bar">
                    <p class="slider_box_slider J_slider" style="left:0%">
                        <p class="slider_box_slider_label J_value"></p>
                        <i class="slider_box_slider_touch"></i>
                    </p>
                    <p class="slider_box_line">
                        <span class="slider_box_line_fill J_fill" style="width:0%"></span>
                    </p>
                </p>
                <i class="slider_box_icon icon light"></i>
            </p>
        </p>
    </p>
    <script src="/js/sea.js"></script>
    <script>
        seajs.config({
            base: '/js/',            //map: [[/^(.*\.(?:css|js))(.*)$/i, "$1"]],            charset: 'utf-8'
        });
        seajs.use("baby");    </script></body></html>

View Code

自己的實現就拿掉了遮罩和config部分,將sea.js的目錄改到自己對應的目錄即可:

   seajs.config({
            base: '/js/',            //map: [[/^(.*\.(?:css|js))(.*)$/i, "$1"]],
            charset: 'utf-8'
        });
        seajs.use("baby");

這個baby(命名和產品有關~)就相當于是lamp。 另外就是,修改請求地址。也就是通過后臺調用api來實現getdate和setdata。第一版我修改的js和lamp.js的差別不大 就增加了一個log為了調試,修改調用路徑。

define(function (require) {    var $ = require("common/zepto");    var util = require("util/util");    var ProcessBar = require("ui/process-bar");  
    var requestData = {
        services: {
            lightbulb: { alpha: 10 },
            air_conditioner: {},
            power_switch: {},
            operation_status: { status: 0 }
        },
        device_type: util.getQuery("device_type"),
        device_id: util.getQuery("device_id"),
        user: '',
    };    var lastModTime = 0;    var powerBtn = $("#powerBtn"), // 開關按鈕       lightBar;    function log(msg, arg) {
        console.log(msg, arg);
        msg = JSON.stringify(msg);        if (arg) {
            msg = msg + "," + JSON.stringify(arg);
        }
        $.post('/device/log', { msg: msg });
    }
    (function () {
        bindEvent();        if (!requestData.device_id || !requestData.device_type) {
            alert("頁面缺少參數");            return;
        }
        powerBtn.on("tap", togglePower); // 開關按鈕事件        initBar();
        queryDevice();
    })();    function bindEvent() {
        $(".footer .nav_side li").click(function () {
            activePage($(this).data("index"), $(this));
        });
    }    function activePage(index, $self) {
        $self.parent('li').addClass("on");
        $body.find('.page:eq(' + index + ')').addClass("active").siblings().removeClass("active");
    }    /**
     * 初始化進度條     */
    function initBar() {
        log("初始化lightBar");
        lightBar = new ProcessBar({
            $id: "lightBar",
            min: 0,
            stepCount: 100,
            step: 1,
            touchEnd: function (val) {
                requestData.services.lightbulb.alpha = val;
                log("亮度值為:" + val);
                setData();
            }
        });
    }    /**
   * 開關按鈕事件   */
    function togglePower() {
        $("#switchBtn").toggleClass("on").toggleClass("off");        if (requestData.services.operation_status.status == 0) {
            requestData.services.operation_status.status = 1;
            log("燈的狀態:1");
        } else {
            requestData.services.operation_status.status = 0;
            log("燈的狀態:0");
        }
        setData();
    }    function queryDevice() {
        $.getJSON('/device/RequestDeviceStatus', { reqstr: JSON.stringify(requestData) },            function (data) {
                console.log(data);                if (data.error_code == 0) {                    //請求成功;                    initInterval();
                    console.log("查詢成功");
                } else {
                    alert(data.error_msg);
                }
            });
    }    /**
   * 輪詢   */
    function initInterval() {
        getData();
        setInterval(function () {            if ((new Date().getTime() - lastModTime) > 2000) { // 當有設置操作時,停止1s輪詢,2秒后繼續輪詢                getData();
            }
        }, 1000);
    }    function setData() {
        $.getJSON('/device/RequestDeviceStatus', { reqstr: JSON.stringify(requestData) }, function (data) {
            console.log(data);
            lastModTime = new Date().getTime();            if (data.error_code == 0) {
                console.log("設置成功");
            }
        });
    }    function getData() {
        $.post('/device/getData', function (data) {
            $("#reData").html(JSON.stringify(data));            if (data && data.services) {
                renderPage(data);
            }
        });
    };    function renderPage(json) {        if (!json.services) {            return;
        }
        console.log("json", json);
        requestData = json;        if (requestData.services.operation_status.status == 0) {
            $("#switchBtn").addClass("off").removeClass("on");
        } else {
            $("#switchBtn").addClass("on").removeClass("off");
        }
        lightBar.setVal(requestData.services.lightbulb.alpha);
    }
})

View Code

我將pageParam和device_status做成了一個對象。requestData。

    var requestData = {
        services: {
            lightbulb: { alpha: 10 },           // air_conditioner: {},            power_switch: {},
            operation_status: { status: 0 }
        },
        device_type: util.getQuery("device_type"),
        device_id: util.getQuery("device_id"),
        user: '',
    };

后臺就是兩個主要方法,一個設置(查詢頁就是設置),一個讀取。這里又回到上一節的內容了。我先查詢一次設備(lamp中在綁定)之后,再進入循環。

setdata

public ActionResult RequestDeviceStatus(string reqstr)
        {            if (string.IsNullOrEmpty(reqstr))
            {                return Json("-1", JsonRequestBehavior.AllowGet);
            }            var args = JsonConvert.DeserializeObject<RequestData>(reqstr);
            args.user = getOpenId(args.device_type, args.device_id);
            Session["warmwood"] = args.device_id;            //args.services.air_conditioner = null;
            args.services.power_switch = null;
            args.services.lightbulb.value_range = null;            try
            {                var res = wxDeviceService.RequestDeviceStatus(getToken(), args);                if (res.error_code != 0)
                {
                    Logger.Debug("error_code:" + res.error_code);
                    Logger.Debug("error_msg:" + res.error_msg);
                }                return Json(res, JsonRequestBehavior.AllowGet);
            }            catch (ErrorJsonResultException e)
            {                if (e.JsonResult.errcode.ToString() == "access_token expired")
                {                    //重新獲取token                }
                Logger.Debug("請求失敗:" + e.Message);
            }            return Json("-1", JsonRequestBehavior.AllowGet);
        }

這個方法先將字符串轉成我們的RequestData對象,RequestData如下:

    public class RequestData
    {        public string device_type { get; set; }        public string device_id { get; set; }        public string user { get; set; }        public Service services { get; set; }        public object data { get; set; }
    }

services就是根據微信services定義的,可以參考上一節,然后用wxDeviceService請求。

 var res = wxDeviceService.RequestDeviceStatus(getToken(), args);                if (res.error_code != 0)
                {
                    Logger.Debug("error_code:" + res.error_code);
                    Logger.Debug("error_msg:" + res.error_msg);
                }   return Json(res, JsonRequestBehavior.AllowGet);

設置之后馬上會受到是否設置成功的響應,error_code 可能為50019(設置頻繁),50013(網絡問題)等等。真正的設備狀態是通過getdata獲得的。

getdata

        public JsonResult GetData()
        {            var userdata = getUserWxData();            return Json(userdata.ResponseData, JsonRequestBehavior.AllowGet);
        }

getdata比較簡單就是返回數據,但是這個數據是在ReceiveWXMsg方法中設置的。這個上一節也講過,這是在公眾號后臺我們設置的一個地址。

   public string ReceiveWXMsg()
        {
            //somecode
            try
            {                var userdata = getUserWxData();                var data = wxDeviceService.GetDeviceStatus(Request);
                userdata.ResponseData = data;
                Logger.Debug("ResponseData.asy_error_code:" + userdata.ResponseData.asy_error_code);
                Logger.Debug("ResponseData.asy_error_msg:" + userdata.ResponseData.asy_error_msg);
                setUserWxData(userdata);
            }            catch (Exception e)
            {
                Logger.Debug(e.Message);
            }            return echostr;
        }

wxDeviceService如下:

微信硬件H5開發之控制燈光微信硬件H5開發之控制燈光

using System;using System.Collections.Generic;using System.Diagnostics;using System.IO;using System.Linq;using System.Net.Http;using System.Web;using Newtonsoft.Json;using Niqiu.Core.Domain.Common;using Senparc.Weixin;using Senparc.Weixin.Exceptions;using SendHelp= Senparc.Weixin.CommonAPIs.CommonJsonSend;namespace Portal.MVC.WXDevice
{    public class WxDeviceService:IWxDeviceService
    {        //private readonly ICacheManager _cacheManager;        //public WxDeviceService(ICacheManager cacheManager)        //{        //    _cacheManager = cacheManager;        //}
        public TokenResult GetAccessToken()
        {            var url = string.Format(WxDeviceConfig.AccessTokenUrl, WxDeviceConfig.AppId, WxDeviceConfig.APPSECRET);            var res = SendHelp.Send<TokenResult>(null, url, null, CommonJsonSendType.GET);            return res;
        }        public WxResponseData GetDeviceStatus(HttpRequestBase request)
        {
            Stream postData = request.InputStream;
            StreamReader sRead = new StreamReader(postData);            string postContent = sRead.ReadToEnd();            if (!string.IsNullOrEmpty(postContent))
            {
                Logger.Debug("收到數據:" + postContent);
            }            try
            {                var data = JsonConvert.DeserializeObject<WxResponseData>(postContent);
                data.rawStr = postContent;
                Logger.Debug("轉換消息狀態:" + data.asy_error_msg);                return data;
            }            catch (Exception e)
            {
                Logger.Debug(e.Message);                throw;
            }
        }        public OpenApiResult RequestDeviceStatus(string accessToken, RequestData data)
        {            var url = string.Format(WxDeviceConfig.GetDeviceStatusUrl, accessToken);            return SendHelp.Send<OpenApiResult>(accessToken, url, data);
        }        public OpenApiResult SetDevice(string accessToken, RequestData data)
        {            var url = string.Format(WxDeviceConfig.GetDeviceStatusUrl, accessToken);            return SendHelp.Send<OpenApiResult>(accessToken, url, data);
        }        public string GetOpenId(string accessToken,string deviceType,string deviceId)
        {            try
            {                var url = string.Format(WxDeviceConfig.GetOpenid, accessToken, deviceType, deviceId);                var res = SendHelp.Send<OpenIdResult>(accessToken, url, null, CommonJsonSendType.GET);                return res.GetOpenId();
            }            catch (ErrorJsonResultException e)
            {
                Logger.Debug(e.Message);                throw;
            }
        }
    }
}

View Code

這方法讀到數據后就交給了userdata 緩存起來。在getdata方法中返回。

   private UserWxData getUserWxData()
        {            var target = _cacheManager.Get<UserWxData>(userKey) ?? new UserWxData();            return target;
        }        private string userKey
        {            get
            {                var key = Session["warmwood"] ?? Session.SessionID;
                Session.Timeout = 240;                return key.ToString();
            }
        }

View Code

UserWxData是我自定義的對象,包含了下面的幾個熟悉。

    public class UserWxData
    {        private WxResponseData _responseData;        public UserWxData()
        {
            CreateTime = DateTime.Now;
        }        public DateTime CreateTime { get; set; }        public TokenResult AccessToken { get; set; }        public WxResponseData ResponseData
        {            get { return _responseData??(_responseData=new WxResponseData()); }            set { _responseData = value; }
        }        public string OpenId { get; set; }
    }

比較重要的是token和responseData。WxResponseData 也就是最終要發給頁面上的對象。包含你需要的功能的參數。

 public class WxResponseData
    {        public int asy_error_code { get; set; }        public string asy_error_msg { get; set; }        public string create_time { get; set; }        public string msg_id { get; set; }        /// <summary>
        /// notify 說明是設備變更        /// set_resp 說明是設置設備        /// get_resp 說明獲取設備信息        /// </summary>
        public string msg_type { get; set; }        public string device_type { get; set; }        public string device_id { get; set; }        public object data { get; set; }        public Service services { get; set; }        public string user { get; set; }        public string rawStr { get; set; }
    }

severices看自己的設備定義,比如我現在包含了空調,開關,溫度濕度。

    public class Service
    {        public lightbulb lightbulb { get; set; }        public air_conditioner air_conditioner { get; set; }        public power_switch power_switch { get; set; }        public operation_status operation_status { get; set; }        public tempe_humidity tempe_humidity { get; set; }
    }

到這兒,整個過程就講完了,獲取token和openid上一節講過,就不贅述了。如果后端是node的話,就不需要這么多的類型轉換了。

最后可以看下效果:

微信硬件H5開發之控制燈光

相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!

推薦閱讀:

JS里特別好用的輕量級日期插件

JavaScript關于IE8兼容問題的處理

以上就是微信硬件H5開發之控制燈光的詳細內容,更多請關注php中文網其它相關文章!


微信提供公眾平臺、朋友圈、消息推送等功能,用戶可以通過“搖一搖”、“搜索號碼”、“附近的人”、掃二維碼方式添加好友和關注公眾平臺,同時微信將內容分享給好友以及將用戶看到的精彩內容分享到微信朋友圈。

溫馨提示:喜歡本站的話,請收藏一下本站!

本類教程下載

系統下載排行

在线看毛片视频-国产免费av在线-欧美日韩一区二区三区-国产成人无码av在线播放无广告-亚洲人va欧美va人人爽-国产第一草草-西班牙黄色片-四虎在线网站8848-最新av片免费网站入口-东京热无码中文字幕av专区-日本大人吃奶视频xxxx-欧美精品一区二区三区四区五区-国产片天天弄-国产免费内射又粗又爽密桃视频-欧美爱爱网站-日韩v欧美
  • <li id="86scu"><menu id="86scu"></menu></li>
    <li id="86scu"></li>
    <button id="86scu"></button>
  • <s id="86scu"></s><button id="86scu"><menu id="86scu"></menu></button>
  • 国内av一区二区| 男人女人黄一级| 波多野结衣网页| 亚洲精品永久视频| 九九热免费在线观看| 蜜臀av午夜一区二区三区| 精品人妻人人做人人爽| 一区二区三区日韩视频| 中文 日韩 欧美| 五月天婷婷影视| 手机精品视频在线| 肉色超薄丝袜脚交| 91av视频免费观看| 91丝袜超薄交口足| 成人手机视频在线| 国产盗摄视频在线观看| 国产三级中文字幕| 精品无码av无码免费专区| 欧美一级特黄aaaaaa在线看片| 亚洲欧美天堂在线| 欧美xxxx吸乳| 免费观看国产视频在线| 国产日产欧美一区二区| 妞干网视频在线观看| 波多野结衣之无限发射| 国产一区二区网| 乌克兰美女av| 男人的天堂成人| 波多野结衣家庭教师在线播放| xxx国产在线观看| 91aaa精品| 可以在线看的av网站| 92看片淫黄大片一级| 一女二男3p波多野结衣| 久久久天堂国产精品| 男人靠女人免费视频网站| 美女喷白浆视频| 亚洲制服在线观看| 91午夜在线观看| 国产真人无码作爱视频免费| www.超碰97.com| 欧美日韩不卡在线视频| 91蝌蚪视频在线观看| 五月婷婷之综合激情| 亚洲天堂第一区| 成人黄色一区二区| 三上悠亚免费在线观看| 国产精品无码av无码| 老司机午夜网站| 日韩毛片在线免费看| 中国一级大黄大黄大色毛片| 国产麻花豆剧传媒精品mv在线| 国产福利视频在线播放| 亚洲网中文字幕| 国产熟女高潮视频| 男女啪啪免费观看| 午夜免费一区二区| 欧美啪啪免费视频| 欧美一级免费在线观看| 国产1区2区在线| 狠狠干视频网站| 天天色综合社区| 一本大道熟女人妻中文字幕在线 | 国产女主播av| 久久综合久久色| 国产午夜精品视频一区二区三区| 五月六月丁香婷婷| 日av中文字幕| 国产美女在线一区| 红桃视频 国产| 国产男女在线观看| 300部国产真实乱| 欧美又黄又嫩大片a级| 日韩av资源在线| 777av视频| 欧美黄色免费网址| 亚洲无吗一区二区三区| 青青草综合在线| 精品久久免费观看| 亚洲 欧美 另类人妖| 久久综合久久色| 黄在线观看网站| 国产精品秘入口18禁麻豆免会员 | wwwwxxxx日韩| 青青草av网站| 美女一区二区三区视频| 欧美三级理论片| 99视频在线视频| 中文字幕第80页| 国产成人久久777777| 精品国产免费av| 国产av国片精品| 国产婷婷一区二区三区| 国产性生活免费视频| 福利在线小视频| 亚洲中文字幕无码一区二区三区| 男人草女人视频| 日本a在线天堂| 九九爱精品视频| 午夜肉伦伦影院| 亚州精品一二三区| 亚洲精品永久视频| 一道本在线观看视频| www.99riav| 91成人在线观看喷潮教学| 黄色动漫网站入口| 99视频精品免费| 成年网站在线播放| 色姑娘综合天天| 乱熟女高潮一区二区在线| 国产一区二区四区| 国产肥臀一区二区福利视频| 中文字幕在线导航| 男插女免费视频| 国产精品无码人妻一区二区在线 | 亚洲精品无码国产| 能在线观看的av| 校园春色 亚洲色图| 91网址在线观看精品| 亚洲av综合色区| 黄色av网址在线播放| 男人亚洲天堂网| 国产性生活一级片| a级免费在线观看| 久久久久国产精品熟女影院| 亚洲这里只有精品| av电影一区二区三区| 欧日韩免费视频| 日本久久精品一区二区| 懂色av一区二区三区四区五区| av中文字幕网址| 日韩a级黄色片| 可以看污的网站| 精品无码一区二区三区在线| 欧美美女性视频| 国产成人无码a区在线观看视频| 精品视频在线观看一区二区| 欧美日韩第二页| 精品久久久无码人妻字幂| 杨幂毛片午夜性生毛片| 狠狠干视频网站| 日本超碰在线观看| 免费无码毛片一区二三区| 男人搞女人网站| 热99这里只有精品| 好色先生视频污| 亚洲高清免费在线观看| 日韩伦理在线免费观看| 国产a级片免费看| 九色porny自拍| 37pao成人国产永久免费视频| 可以在线看的黄色网址| 国产精品69久久久| 黑人巨大国产9丨视频| 国产wwwxx| 精品少妇无遮挡毛片| 国产freexxxx性播放麻豆 | 日本www在线视频| 欧美极品少妇无套实战| 日本一二三四区视频| 五月天婷婷亚洲| 欧美大尺度做爰床戏| 欧美aⅴ在线观看| 尤物av无码色av无码| 亚洲精品久久久久久久蜜桃臀| 久久精品国产sm调教网站演员| 91成人在线观看喷潮教学| 成人在线免费观看视频网站| 日本不卡一区二区三区四区| 特黄视频免费观看| 日本中文字幕精品—区二区| 97视频在线免费播放| 日韩av片在线看| 一本大道熟女人妻中文字幕在线 | 伊人五月天婷婷| 亚洲自拍偷拍一区二区三区| 欧美xxxx吸乳| 免费网站在线观看视频| 欧美一级欧美一级| 日本免费黄视频| www.涩涩涩| 黄色污污在线观看| 美女日批免费视频| 天天操,天天操| 黄黄视频在线观看| www.com毛片| www.com黄色片| 免费观看国产视频在线| www国产精品内射老熟女| 在线免费视频a| 久久精品国产精品亚洲精品色| 高清av免费看| 国产aaaaa毛片| 九九爱精品视频| 欧美性久久久久| 亚洲高清在线免费观看| 日本美女久久久| 国产传媒久久久| 欧美一区二区三区爽大粗免费| 激情五月俺来也|