IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 微信小程序(api、开发能力-授权-获取用户信息-获取用户手机号、WeUI框架、云开发) -> 正文阅读

[移动开发]微信小程序(api、开发能力-授权-获取用户信息-获取用户手机号、WeUI框架、云开发)

三、api

1.API概述

小程序开发框架提供丰富的微信原生 API,可以方便的调起微信提供的能力,如获取用户信息,本地存储,支付功能等。

2.api分类

监听api

我们约定,以 on 开头的 API 用来监听某个事件是否触发;

同步api

我们约定,以 Sync 结尾的 API 都是同步 API,j直接接取函数返回的结果即可不需要等待。

异步api

大多数 API 都是异步 API,如 wx.requestwx.login 等。异步api方法主体是object结构,都有success/fail/complete

几乎所有 的异步api都支持promise(前提是基础库版本在2.10.2),

部分接口如 downloadFile, request, uploadFile, connectSocket, createCamera(小游戏)本身就有返回值, 它们的 promisify 需要开发者自行封装。

云开发api

wx.cloud.database();

wx.cloud.callFunction();

3.网络api

语法

wx.request()
注意:项目上线之前一定要将项目中用到的业务域名在微信公众后台注册备案(生效时间5分钟左右);
?
在本地开发测试期间我们为了开发方便可以先不去配置域名信息,只需要将微信开发者工具中的不校验选项设置即可,但是上线之前一定配置好并测试没有问题;
?
微信小程序中不存在跨域问题 ?  防止跨域: csrf:跨站点请求伪造

?

封装网络请求(promise)

微信小程序中网络请求默认不支持promise,需要自己封装
?
1.新建utils/config.js
    // 定义请求域名地址信息
 ?  let URL = 'https://route.showapi.com';
?
 ?  // 导出信息
 ?  module.exports={
 ? ? ?  URL
 ?  }
 ? ?
2.新建utils/request.js
    // 引入请求地址
 ?  let {URL} = require('./config.js');
?
?
 ?  /**
 ? ? * 定义并导出promise版本网络请求
 ? ? * options:{
 ? ? * ? ?  url:请求地址
 ? ? * ? ?  method:请求方式
 ? ? * ? ?  data:请求参数
 ? ? * ? ?  header:请求头
 ? ? * ? ?  success:成功回调
 ? ? * ? ?  fail: 失败回调
 ? ? * }
 ? ? * */ 
 ? ? export default (options)=>{
 ? ? ?  //  重写请求地址
 ? ? ?  let url = URL+options.url;console.log(url)
 ? ? ?  return new Promise((resolve,reject)=>{
 ? ? ? ? ?  wx.request({
 ? ? ? ? ? ?  url,
 ? ? ? ? ? ?  method:options.method || 'get',
 ? ? ? ? ? ?  data: options.data || {},
 ? ? ? ? ? ?  header: options.header || {
 ? ? ? ? ? ? ? ?  "content-type":"application/json"
 ? ? ? ? ? ?  },
 ? ? ? ? ? ?  success:res=>{resolve(res.data)},
 ? ? ? ? ? ?  fail:err=>{reject(err)}
 ? ? ? ? ?  })
 ? ? ?  })
 ? ? }
?
3.在首页使用
?
    // 引入网络请求模块
    import http from '../../utils/request';
?
    // 获取分类数据
 ?  async getData(){
 ? ?  // 3.使用async  awaite 语法糖 请求数据  (使用语法糖的时候一定勾选将js编译成ES5,如下图所示)
 ? ?  // let cateData = await http({
 ? ?  // ? url:'/1700-1',
 ? ?  // ? data:{
 ? ?  // ? ? showapi_appid:100079,
 ? ?  // ? ? showapi_sign:'9e038adb10ef4cf68db6bc8d0feed220'
 ? ?  // ? }
 ? ?  // })
?
 ? ?  // 2.使用promise 请求数据
 ? ?  http({
 ? ? ?  url:'/1700-1',
 ? ? ?  data:{
 ? ? ? ?  showapi_appid:100079,
 ? ? ? ?  showapi_sign:'9e038adb10ef4cf68db6bc8d0feed220'
 ? ? ?  }
 ? ?  })
 ? ?  .then(res=>{
 ? ? ?  // 给页面赋值
 ? ? ?  this.setData({
 ? ? ? ?  cateList:res.showapi_res_body.storylist
 ? ? ?  });
?
 ? ? ?  // 将数据缓存到本地一份 [{},{},{}]
 ? ? ?  wx.setStorageSync('cateList', res.showapi_res_body.storylist)
 ? ?  })
?
?
 ? ?  //1.通过get方式获取数据
 ? ?  // wx.request({
 ? ?  // ? url: 'https://route.showapi.com/1700-1',
 ? ?  // ? method:'get',
 ? ?  // ? data:{
 ? ?  // ? ? showapi_appid:100079,
 ? ?  // ? ? showapi_sign:'9e038adb10ef4cf68db6bc8d0feed220'
 ? ?  // ? },
 ? ?  // ? success:res=>{
 ? ?  // ? ? // 给页面赋值
 ? ?  // ? ? this.setData({
 ? ?  // ? ? ? cateList:res.data.showapi_res_body.storylist
 ? ?  // ? ? })
 ? ?  // ? },
 ? ?  // ? fail:err=>{console.log(err)}
 ? ?  // }) 
 ?  },
?

4.缓存api

地址:wx.setStorageSync(string key, any data) | 微信开放文档

小程序中的本地缓存原理基本同pc端中localstorage ,将数据存储在本地缓存中指定的 key 中。除非用户主动删除或因存储 空间原因被系统清理,否则数据都一直可用。单个 key 允许存储的最大数据长度为 1MB,所有数据存 储上限为 10MB。

缓存api功能分类:存储(set) 获取(get) 根据key删除一个(remove) 清除所有 (clear) 获取缓存详情(info)

应用场景:

存储用户的账号信息 存储业务数据 存储收藏数据 记录用户的访问日志(时间) 购物车数据

结合童话故事使用,如首页将故事分类数据添加至缓存节省网络请求开销,列表页面将故事收藏值本地缓存中

5.界面api

地址:wx.showToast(Object object) | 微信开放文档

常用界面API:交互类、导航类等

结合童话故事案例使用,如动态设置列表页面导航标题内容,导航背景色、前景色,导航数据加载提示效果、设置数据加载提示框等

封装数据加载提示方法
1.新建utils/tip.js
    
 ?  // 定义数据请求|更新提示方法
 ?  const load=(title="数据加载中...")=>{
 ? ? ?  wx.showNavigationBarLoading();
 ? ? ?  wx.showLoading({title})
 ?  }
?
 ?  // 定义关闭数据请求|更新提示方法
 ?  const hideLoad=()=>{
 ? ? ?  wx.hideNavigationBarLoading();
 ? ? ?  wx.hideLoading()
 ?  }
?
 ?  // 导出
 ?  module.exports={
 ? ? ?  load,
 ? ? ?  hideLoad
 ?  }
 ? ?
2.故事列表页面使用
?
    // 引入提示模块文件
    let {load,hideLoad} = require('../../utils/tip')
?
 ?  onLoad: function (options) {
?
 ? ? ?  // 设置导航栏左侧数据加载动画 数据加载load
 ? ? ?  load();
 ? ? ?  ....................
 ? ? ? ?
 ? ? 
 ?  // 获取列表数据
 ?  getList(classifyId){
 ? ? ?  wx.request({
 ? ? ? ?  ...........
 ? ? ? ? ?  success:res=>{
 ? ? ? ? ? ?  ......................
 ? ? ? ? ? ? ?  // 关闭加载动画
 ? ? ? ? ? ? ?  hideLoad()
 ? ? ? ? ?  }....................................
 ? ? ?  }) 
 ?  },
?

四、开发能力-授权

1.概述

(1)微信小程序中部分api函数使用需要经过用户授权同意才能调用,比如获取用户信息,保存图片到相册等,我们把这些接口按使用范围分成多个 scope ,用户选择对 scope 来进行授权,当授权给一个 scope 之后,其对应的所有接口都可以直接使用。 (2)此类接口调用时:

  • 如果用户未接受或拒绝过此权限,会弹窗询问用户,用户点击同意后方可调用接口;

  • 如果用户已授权,可以直接调用接口;

  • 如果用户已拒绝授权,则不会出现弹窗,而是直接进入接口 fail 回调。请开发者兼容用户拒绝授权的场景。

    ?

2.检测授权状态

wx.getSetting()

3.主动发起授权请求

开发者可以使用 wx.authorize 在调用需授权 API 之前,提前向用户发起授权请求。

wx.authorize()

4.再次唤起授权设置界面

为了避免我们通过wx.authorize方法发起主动授权后遭到用户再次拒绝问题,我们可以使用以下两种方式打开设置界面:

1.用户可以在小程序设置界面(「右上角」 - 「关于」 - 「右上角」 - 「设置」)中控制对该小程序的授权状态。

2.使用wx.openSetting()再次唤起授权设置界面。

wx.openSetting(),此方法不能直接调用,需要引导用户主动触发,比如通过点击事件或者消息对话框。
直接使用会报以下错误如下:
    openSetting:fail只能被用户TAP手势调用

代码案例:

以下是以主动获取用户手机的录音功能为例,我们可以在项目的入口处(app.js-->app()方法)检测权限进而引导用户授权。只要用户授权,我们就可以在项目的任何页面去使用录音功能。
?
  /**
 ? * 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
 ? */
  onLaunch: function () {
 ?
 ?  // 测试使用录音接口
 ?  // wx.startRecord({
 ?  // ? success: (result) => {},
 ?  // })
?
?
 ?  // 1.首先检测要使用的接口是否已经授权
 ?  wx.getSetting({
 ? ?  success:res=>{
 ? ? ?  if(res.authSetting['scope.record']){
 ? ? ? ?  console.log('可以正常使用录音接口');
 ? ? ?  }else{
 ? ? ? ?  // 2.引导用户授权
 ? ? ? ?  wx.authorize({
 ? ? ? ? ?  scope: 'scope.record',
 ? ? ? ? ?  success:res=>{
 ? ? ? ? ? ?  // 用户已经同意小程序使用录音功能,后续调用 wx.startRecord 接口不会弹窗询问
 ? ? ? ? ? ?  console.log(res)
 ? ? ? ? ?  },
 ? ? ? ? ?  fail:err=>{
 ? ? ? ? ? ?  console.log('用户拒绝了授权');
 ? ? ? ? ? ?  // 3.兼容用户再次拒绝的场景
 ? ? ? ? ? ?  // 3.1引导用户自主设置权限,用户可以在小程序设置界面(「右上角」 - 「关于」 - 「右上角」 - 「设置」)中控制对该小程序的授权状态。
 ? ? ? ? ? ?  // 3.2引导用户主动触发再次唤起授权界面的api函数即可( 打开设置界面,引导用户开启授权)
 ? ? ? ? ? ?  wx.showModal({
 ? ? ? ? ? ? ?  title:'温馨提示',
 ? ? ? ? ? ? ?  content:'是否再次授权!',
 ? ? ? ? ? ? ?  success:res=>{
 ? ? ? ? ? ? ? ?  if(res.confirm){
 ? ? ? ? ? ? ? ? ?  wx.openSetting({
 ? ? ? ? ? ? ? ? ? ? ?  success:res=>{
 ? ? ? ? ? ? ? ? ? ? ? ?  console.log('再次唤起成功')
 ? ? ? ? ? ? ? ? ? ? ?  },
 ? ? ? ? ? ? ? ? ? ? ?  fail:err=>{console.log('唤起失败!')}
 ? ? ? ? ? ? ? ? ?  })
 ? ? ? ? ? ? ? ?  }else{
 ? ? ? ? ? ? ? ? ?  console.log('用户再此拒绝了!')
 ? ? ? ? ? ? ? ?  }
 ? ? ? ? ? ? ?  }
 ? ? ? ? ? ?  })
 ? ? ? ? ?  }
 ? ? ? ?  })
 ? ? ?  }
 ? ?  }
 ?  })
  },

五、开放能力-获取用户信息

1.通过API获取用户信息

地址:wx.getUserProfile(Object object) | 微信开放文档

注意获取用户信息的api方法已经更新,之前方案是通过button组件引导用户首先授权再次使用wx.getUserInfo()获取用户的信息(头像、昵称等),目前更换为wx.getUserProfile()api方法,每次请求都会弹出授权窗口,用户同意后返回 userInfo。该接口用于替换 wx.getUserInfo

注意,该接口每次触发否会弹窗;不管上次用户是拒绝还是同意 ,所以为了后期开发方便我们可以在用户同意后将获取到的用户信息存入本地缓存供后期业务使用

user.wxml
    
 ?  <view class="info">
?
 ? ? ?  <!-- 用户授权信息 -->
 ? ? ?  <block wx:if="{{buffer}}">
 ? ? ? ? ?  <image src="{{userInfo.avatarUrl}}"></image>
 ? ? ? ? ?  <text>{{userInfo.nickName}}</text>
 ? ? ?  </block>
?
 ? ? ?  <!-- 用户没有授权 -->
 ? ? ?  <button wx:else bindtap="getUserInfo">请授权</button>
?
 ?  </view>
 ? ?
 ? ?
user.js
?
     ?  /**
 ? ? ? ? * 页面的初始数据
 ? ? ? ? */
 ? ? ?  data: {
 ? ? ? ? ?  buffer:false,//默认关闭
 ? ? ? ? ?  userInfo:{},//用户信息
 ? ? ?  },
?
 ? ? ?  // 获取用户的信息
 ? ? ?  getUserInfo(){
 ? ? ? ? ?  wx.getUserProfile({
 ? ? ? ? ? ? ?  desc: '用于完善会员信息',
 ? ? ? ? ? ? ?  success:res=>{
 ? ? ? ? ? ? ? ? ?  console.log(res)
 ? ? ? ? ? ? ? ? ?  // 赋值页面
 ? ? ? ? ? ? ? ? ?  this.setData({userInfo:res.userInfo,buffer:true})
 ? ? ? ? ? ? ? ? ?  // 将用户信息缓存到本地
 ? ? ? ? ? ? ? ? ?  wx.setStorageSync('userInfo', res.userInfo)
 ? ? ? ? ? ? ?  },
 ? ? ? ? ? ? ?  fail:err=>{console.log('失败');}
 ? ? ? ? ?  })
 ? ? ?  },
 ? ? ?  /**
 ? ? ? ? * 生命周期函数--监听页面加载
 ? ? ? ? */
 ? ? ?  onLoad: function (options) {
 ? ? ? ? ?  // 直接使用获取用户信息的方法
 ? ? ? ? ?  //错误实例: wx.getUserProfile({
 ? ? ? ? ?  // ? desc: '用于完善会员信息',
 ? ? ? ? ?  // ? success:res=>{console.log('获取成功');},
 ? ? ? ? ?  // ? fail:err=>{console.log('失败');}
 ? ? ? ? ?  // })
?
 ? ? ? ? ?  // 判断缓存是否有用户的信息
 ? ? ? ? ?  let userInfo = wx.getStorageSync('userInfo') ||'';
 ? ? ? ? ?  if(userInfo != ''){
 ? ? ? ? ? ? ?  this.setData({userInfo,buffer:true})
 ? ? ? ? ?  }else{
 ? ? ? ? ? ? ?  wx.showToast({
 ? ? ? ? ? ? ? ?  title: '请先授权!',
 ? ? ? ? ? ? ? ?  icon:'error',
 ? ? ? ? ? ? ? ?  image:'../../images/personal/tips1.png',
 ? ? ? ? ? ? ? ?  mask:true
 ? ? ? ? ? ? ?  })
 ? ? ? ? ?  }
 ? ? ?  }

六、开放能力-获取用户手机号

(1)需要用户主动触发才能发起获取手机号接口,该功能不由 API 来调用,需用 button 组件的点击来触发

(2)调用 wx.login 登录获取code登录令牌。后端服务器使用 code 换取的 sessionKey 来解密加密的手机号

(3)目前该接口针对非个人开发者,且完成了认证的小程序开放(不包含海外主体),可以使用测试号

注册微信小程序测试号地址:测试号管理 | 微信公众平台

1.获取加密手机号

<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber"></button>

2.微信登录

wx.login()
通过微信登录获取用户的临时登录令牌code码,code有效期是5分钟,接着将code码发送给自己的服务端,服务端获取用户在微信服务器上的的session_key(加解密用户私密数据的钥匙)和用户的openid(用户唯一标识符);进而自己的服务端可以通过session_key来解密用户的私密数据,比如:手机号码、微信运动步数等 

3.后端解密开放数据

小程序可以通过各种前端接口获取微信提供的开放数据,但是开发者服务端获取这些开放数据时,需要对开放数据进行解密;

前端获取到的手机号是加密的需要后端解密,解密完毕直接返回给前端即可

小程序端代码案例:

phone.wxml
    <!-- 获取加密的手机号 -->
 ?  <button open-type="getPhoneNumber" bindgetphonenumber='getPhone'>获取手机号</button>
?
 ?  <!-- 获取手机号其实就是微信一键登录 -->
 ?  <!-- <button open-type="getPhoneNumber" bindgetphonenumber='getPhone'>微信一键登录        </button> -->
 ? ?
phone.js
      getPhone(e){
 ? ? ?  console.log(e)
 ? ? ?  // 获取加密手机号数据
 ? ? ?  let {encryptedData,iv} = e.detail; 
 ? ? ?  // 通过wx登录方法获取登录令牌(有效期5分钟)
 ? ? ?  wx.login({
 ? ? ? ? ? success:res=>{
 ? ? ? ? ? ? ?  //将加密数据和code发送给服务端 (以下是示意代码  跑不通)
 ? ? ? ? ? ? ?  // wx.request({
 ? ? ? ? ? ? ?  // ? url: 'http://localhost:3000',
 ? ? ? ? ? ? ?  // ? data:{
 ? ? ? ? ? ? ?  // ? ? encryptedData,
 ? ? ? ? ? ? ?  // ? ? iv,
 ? ? ? ? ? ? ?  // ? ? code, 
 ? ? ? ? ? ? ?  // ? ? secret:'fae65bd555bec6676441c3678b005a3f' 
 ? ? ? ? ? ? ?  // ? }
 ? ? ? ? ? ? ?  // }) ? ?
 ? ? ? ? ? } 
 ? ?

注意:如果第一次测试弹窗提示需要注册发送短信之类的提示 直接点击工具栏中的 预览 在真机上按照提示验证完毕后再次在开发者工具中模拟测试即可

七、WeUI框架

1.组件库概述

一套基于样式库weui-wxss开发的小程序扩展组件库,同微信原生视觉体验一致的UI组件库,由微信官方设计团队和小程序团队为微信小程序量身设计,令用户的使用感知更加统一。

地址:WeUI组件库简介 | wechat-miniprogram / weui

2.安装配置

1.首先在app.json文件中添加以下配置;
?
"useExtendedLib": {
 ?  "weui": true
  }

3.注册组件

像使用自定义组件一样,注册要使用的组件即可
1.全局注册
    app.json
          "usingComponents": {
 ? ? ? ? ? ? ?  "mp-navigation-bar": "weui-miniprogram/navigation-bar/navigation-bar"
 ? ? ? ? ? ?  }
2.局部注册
    page.json
          "usingComponents": {
 ? ? ? ? ?      "mp-navigation-bar": "weui-miniprogram/navigation-bar/navigation-bar"
 ? ? ? ?  }

4.案例代码(练习)

切记:使用组件前一定先注册要使用的组件
weui.wxml页面
?
 ?  <!-- 自定义导航栏 -->
 ?  <mp-navigation-bar
 ? ? ?  background="red" 
 ? ? ?  back="{{false}}"
 ?  >
 ? ? ?  <!-- 自定义左侧内容 slot -->
 ? ? ?  <view slot='left'>
 ? ? ? ? ?  <text>首页 | </text>
 ? ? ? ? ?  <text bindtap="goBack">返回</text>
 ? ? ?  </view>
 ? ? ?  <!-- 自定义中间内容 -->
 ? ? ?  <view slot='center'>
 ? ? ? ? ?  <icon type="search" color="white"></icon>
 ? ? ? ? ?  <text style="color:white">订单查询</text>
 ? ? ?  </view>
 ?  </mp-navigation-bar>
?
 ?  <!-- 搜索区域 -->
 ?  <mp-searchbar></mp-searchbar>
?
?
app.json:
?
 "usingComponents": {
 ?  "mp-navigation-bar": "weui-miniprogram/navigation-bar/navigation-bar",
 ?  "mp-searchbar": "weui-miniprogram/searchbar/searchbar"
  }

八、云开发 (了解)

就是提供了前端操作服务端的能力,云开发可以理解为后端服务

1.概述

?

开发者可以使用云开发快速开发小程序、小游戏、公众号网页等,并且原生打通微信开放能力。

云开发为开发者提供完整的原生云端支持和微信服务支持,弱化后端和运维概念,无需搭建服务器,使用平台提供的 API 进行核心业务开发,即可实现快速上线和迭代,同时这一,能力,同开发者已经使用的云服务相互兼容,并不互斥。提供了包括数据库、云函数、存储等基础能力

换句话说就是,我们可以将业务数据直接存储在云数据库中、将图片资源可以存储在云存储中,也可以设置运行在云端的云函数来操作数据库、云存储等资源,在云函数端操作云开发资源相对小程序端具有更高的权限,比如在小程序每次查询数据限制为20条,而在云函数端可以每次查询100条;

2.基础能力概述

1.数据库

云开发提供了一个 JSON 数据库,顾名思义,数据库中的每条记录都是一个 JSON 格式的对象。一个数据库可以有多个集合(相当于关系型数据中的表),集合可看做一个 JSON 数组,数组中的每个对象就是一条记录,记录的格式是 JSON 对象。

2.云存储

云开发提供了一块存储空间,提供了上传文件到云端、带权限管理的云端下载能力,开发者可以在小程序端和云函数端通过 API 使用云存储功能。

在小程序端可以分别调用 wx.cloud.uploadFilewx.cloud.downloadFile 完成上传和下载云文件操作。

3.云函数

云函数是一段运行在云端的代码,无需管理服务器,在开发工具内编写、一键上传部署即可运行后端代码。

小程序内提供了专门用于云函数调用的 API。开发者可以在云函数内使用 wx-server-sdk 提供的 getWXContext 方法获取到每次调用的上下文(appidopenid 等),无需维护复杂的鉴权机制,即可获取天然可信任的用户登录态(openid)。

3.新建云开发模板

如下:

?

4.开通云开发、创建环境

?

?

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-11-30 15:43:53  更:2021-11-30 15:44:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:52:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码