目录:
一、HTML5PLUS
二、mui
三、hbuilderx app开发流程
四、hbuilderx app打包流程
五、hbuilder app开发流程
六、hbuilder app打包流程
HTML5PLUS 硬件驱动接口,系统调用接口,相当于jQuery
HTML5PLUS官网:http://www.html5plus.org/
使用方法详见官网 html5+规范:http://www.html5plus.org/doc/h5p.html
蜂鸣声和震动:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
doctype html>
.mui-bar-nav{
background-color: pink;
}
#first_ul{
margin-top: 0;
}
.mui-content ul{
margin-bottom: 10px;
}
h5plus
震动
蜂鸣声
mui.init();
mui.plusReady(function() {
//蜂鸣声
document.getElementById('beep').addEventListener('tap', function() {
plus.device.beep();
});
//震动
document.getElementById("vibrate").addEventListener("tap", function() {
plus.device.vibrate();
});
})
蜂鸣声beep和震动vibrate
获取手机通讯录功能示例(包括打电话功能):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
doctype html>
.mui-bar-nav{
background-color: pink;
}
.mui-content ul{
margin-bottom: 10px;
}
h5plus
通讯录
mui.init();
mui.plusReady(function() {
//通讯录
document.getElementById("contacts").addEventListener("tap",function(){
mui.openWindow({
url:"xingfudao_contact.html",
id:"xingfudao_contact"
});
});
})
xingfudao_h5plus.html(从当前页点击通讯录按钮进入通讯录页面)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
doctype html>
.mui-bar-nav {
background: pink;
}
.mui-title {
color: white;
}
通讯录
mui.init();
mui.plusReady(function() {
//获取通讯录对象
plus.contacts.getAddressBook(
plus.contacts.ADDRESSBOOK_PHONE,
function(addressbook) {
//对回调结果进行处理
addressbook.find([], function(res) {
console.log(JSON.stringify(res));
//创建一个用于存储每个联系人li标签的容器
var li_str = "";
//循环处理res中数据
for (var i = 0; i doctype html>
.mui-bar-nav{
background-color: pink;
}
.mui-content ul{
margin-bottom: 10px;
}
h5plus
相册
mui.init();
mui.plusReady(function() {
document.getElementById("pick").addEventListener("tap", function() {
//单张视频或图片文件的选择
// plus.gallery.pick(
// function(path){
// console.log(path);
// var allImgExt = ".jpg|.jpeg|.gif|.bmp|.png";//图片文件的类型
// var extName = path.substring(path.lastIndexOf(".")).toLowerCase();//将所选文件的扩展名截取并转为小写
// if(allImgExt.indexOf(extName+"|")==-1){//视频文件
// document.getElementById("img").innerHTML='';
// }else{//图片文件
// document.getElementById("img").innerHTML=' ';
// }
// },
// function(e){
// alert("取消照片选择");
// },
// {filter:"none"}
// );
//多个图片或视频文件的选择
plus.gallery.pick(
function(f) { //f表示存储多个文件路径的数组
for (var i in f.files) {
console.log(f.files[i]);
var path = f.files[i];
var allImgExt = ".jpg|.jpeg|.gif|.bmp|.png"; //图片文件的类型
var extName = path.substring(path.lastIndexOf(".")).toLowerCase(); //将所选文件的扩展名截取并转为小写
if (allImgExt.indexOf(extName + "|") == -1) { //视频文件
document.getElementById("img").innerHTML = document.getElementById("img").innerHTML + '';
} else { //图片文件
document.getElementById("img").innerHTML = document.getElementById("img").innerHTML + ' ';
}
}
},
function(e) {
alert("取消照片选择");
}, {
filter: "none",
multiple: true
}
);
});
})
选择手机相册中的图片或视频
APP拍照功能示例:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
doctype html>
.mui-bar-nav{
background-color: pink;
}
.mui-content ul{
margin-bottom: 10px;
}
h5plus
拍照
mui.init();
mui.plusReady(function() {
//拍照
document.getElementById("camera").addEventListener("tap", function() {
//获取摄像头对象
var cmr = plus.camera.getCamera();
var res = cmr.supportedImageResolutions[0]; //分辨率
var fmt = cmr.supportedImageFormats[0]; //格式
console.log("分辨率:" + res);
console.log("格式:" + fmt);
cmr.captureImage(
function(rs) {
var path = "file://" + plus.io.convertLocalFileSystemURL(eval(JSON.stringify(rs)));
console.log("图片路径:" + path);
//动态将图片展示在id为img的容器中
document.getElementById("img").innerHTML = ' ';
},
function(e) {
alert(e.message + "取消拍照");
}, {
resolution: res,
format: fmt
}
);
});
});
拍照并将照片显示出来
音频处理:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
Document
正在播放xxxxxx
暂停
继续
停止
mui.init();
var Sdata = null;
var myplayer = null;
mui.plusReady(function () {
Sdata = plus.webview.currentWebview();
document.getElementById("title").innerText = "正在播放" + Sdata.title;
document.getElementById("cover").src =window.serv_image + Sdata.cover;
myplayer = plus.audio.createPlayer(window.serv_music + Sdata.audio);
myplayer.play();
})
document.getElementById('pause').addEventListener('tap',function () {
myplayer.pause();
})
document.getElementById('resume').addEventListener('tap',function () {
myplayer.resume();
})
document.getElementById('stop').addEventListener('tap',function () {
myplayer.stop();
})
audio 的简单使用示例
扫描二维码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
Document
扫描玩具二维码
mui.init();
var scan = null;
mui.plusReady(function () {
scan = new plus.barcode.Barcode("bcid");
scan.onmarked = inmarked;
scan.start();
})
function inmarked(type,code){
// alert(type +":"+ code)
mui.post(window.serv+ '/validate_code',{
device_key:code
},function(data){
if(data.code == 0){
//打开绑定玩具流程 创建玩具
mui.openWindow({
url:"bind_toy.html",
id:"bind_toy.html",
extras:data.data
})
}else if(data.code==2){
//扫描的二维码信息异常
mui.toast(data.msg);
mui.back();
}else if(data.code==1){
//神秘代码
}
},'json'
);
}
扫描二维码简单示例
录音并上传和发送语言:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
Document
点击播放消息
点击播放消息
按住说话
mui.init({
gestureConfig: {
doubletap: false, //默认为false
longtap: false, //默认为false
swipe: false, //默认为true
drag: false, //默认为true
hold: true, //默认为false,不监听
release: true //默认为false,不监听
}
});
var Sdata = null;
mui.plusReady(function() {
Sdata = plus.webview.currentWebview();
document.getElementById("title").innerText = Sdata.friend_nick;
});
var reco = null;
var filename = null;
document.getElementById('talk').addEventListener('hold', function() {
reco = plus.audio.getRecorder();
reco.record({
filename: "_doc/audio/",
format: "amr"
}, function(path) {
console.log(path);
createUpload(path);
});
})
document.getElementById('talk').addEventListener('release', function() {
reco.stop();
})
function createUpload(path) {
var task = plus.uploader.createUpload(window.serv + "/uploader", {
method: "POST"
},
function(t, status) {
// 上传完成
if(status == 200) {
console.log(JSON.stringify(t));
filename = JSON.parse(t.responseText);
send_str = {
"chat": filename.data.filename,
"to_user": Sdata.friend_id,
"from_user": window.localStorage.getItem("user")
};
var index = plus.webview.getWebviewById("HBuilder");
mui.fire(index, 'send_str', send_str);
create_chat("self","mama.jpg",path);
}
}
);
task.addFile(path, {
key: "recorder"
});
task.addData("key", "value");
task.start();
}
function create_chat(who, avatar,chat) {
var div1class = "leftd";
var spanclass = "leftd_h";
var div2class = "left speech";
if(who == "self") {
div1class = "rightd";
spanclass = "rightd_h";
div2class = "right speech";
}
if(chat.toString().indexOf("_")>-1){
chat = chat;
}else{
chat = window.serv_chat + chat;
}
var div = document.createElement("div");
div.className = div1class;
var span = document.createElement("span");
span.className = spanclass;
var img = document.createElement("img");
img.src = "avatar/" + avatar;
var div2 = document.createElement("div");
div2.className = div2class;
div2.innerText = "点击播放";
div2.onclick = function(){
var player = plus.audio.createPlayer(chat);
player.play();
}
div.appendChild(span);
span.appendChild(img);
div.appendChild(div2);
document.getElementById("chat_list").appendChild(div);
}
document.addEventListener("add_chat",function(data){
create_chat("","toy.jpg",data.detail.filename);
})
chat.html
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from flask import Blueprint,jsonify,send_file,request
from settings import CHATS_PATH
import os
gsa = Blueprint("gsa",__name__)
@gsa.route("/uploader",methods=["POST"])
def uploader():
audio = request.files.get("recorder")
import os
path = os.path.join(CHATS_PATH,audio.filename)
audio.save(path)
os.system(f"ffmpeg -i {path} {path}.mp3")
RET["code"] = 0
RET["msg"] = "上传音频文件"
RET["data"] = {"filename":f"{audio.filename}.mp3"}
return jsonify(RET)
Flask蓝图
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
document.addEventListener("send_str", function(data) {
var send_str = data.detail // {to_user:"toy123",chat:"123123123.amr.mp3"}
ws.send(JSON.stringify(send_str));
});
index.html
Mui 布局框架 = 排版用,相当于bootstrap,内部已封装 HTML5PLUS
Mui官网:https://dev.dcloud.net.cn/mui/
Mui的各功能的使用详见官网文档:https://dev.dcloud.net.cn/mui/ui/
注意 UI组件、窗口管理、事件管理、ajax、代码块等的使用
代码块:组件开发快捷键,详见Mui文档最下方
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
部分常用到的代码块.方便开发.
组件 触发字符
mDoctype(mui-dom结构) mdo ctype
mBody(主体) mbo dy
mScroll(区域滚动容器) msc roll
mrefreshContainer(刷新容器) mre fresh
mHeader(标题栏) mhe ader
mHeader(带返回箭头的标题栏) mhe aderwithBack
mCheckbox(复选框) mch eckbox
mCheckbox(复选框居左) mch eckbox_left
mCheckbox(复选框禁用选项) mch eckbox_disabled
mIcon(图标) mic on
mOffcanvas(侧滑导航-主界面、菜单同时移动) mof fcanvasall
mOffcanvas(侧滑导航-主界面移动、菜单不动) mof fcanvasmain
mOffcanvas(侧滑导航-主界面不动、菜单移动) mof fcanvasmenu
mOffcanvas(侧滑导航-缩放式侧滑(类手机QQ)) mof fcanvasscalable
mText(文本框) min puttext
mText_Search(搜索框) min putsearch
mText_Clear(带清除按钮的文本框) min putclear
mText_Speech(语音输入) min putspeech
mForm(表单) mfo rm
mRadio(单选框) mra dio
mRadio(单选框居左) mra dio_left
mRadio(禁用单选框) mra dio_disable
mRadios(默认选中指定项) mra dio_selected
mPopover(弹出菜单) mpo pover
mprogressbar(进度条-无限循环) mpr ogressbarinfinite
mprogressbar(进度条-有准确值) mpr ogressbar
mActionsheet(H5模式弹出菜单) mac tionsheet
mRange(Label+滑块) mra ngelabel
mSwitch(开关) msw itch
mSwitch(开关 - 蓝色) msw itch_blue
mSwitch(开关Mini) msw itchmini
mSwitch(开关Mini - blue) msw itchmini_blue
mbadge(数字角标) mba dge
mbadge(数字角标无底色) mba dge_inverted
mTab(底部选项卡) mta b
mTabSegmented(div选项卡) mta bsegmented
mTabSegmented(可左右拖动的选项卡) mta bviewpage
mPagination(分页) mpa gination
mList(列表) mli st
mListMedia(图文列表图片居左) mli st_Media_left
mListMedia(图文列表图片居右) mli st_Media_right
mGrid(九宫格) mgr id
mGallery-Table(图文表格) msl ider_gallery_table
mGallery(图片轮播) msl ider_gallery
slide(轮播组件) msl ider
mactionsheet(操作表) act ionsheet
maccordion(折叠面板) mac cordion
mnumbox(数字输入框) mnu mbox
mrefreshContainer(刷新容器) mpu llrefresh
mButton(按钮) mbu tton
mButton(按钮无底色,有边框) mbu tton_outline
mButton(块状按钮) mbu tton_block
init
组件 触发字符
mui.init min
创建子页面( subpage ) minsubpage
预加载页面( preload ) minpreload
刷新组件( pullRefresh ) minpullRefresh
手势事件( getures ) mingesture
侧滑返回( swipeback ) minswipeback
按键绑定(keyeventbind) minkeyevent
重写窗口关闭逻辑(beforeBack) minbeforeback
设置状态栏颜色( setStatusbar ) minstatusbar
预加载数量( preloadlimit ) minprelimit
js组件
组件 触发字符
mui.plusReady() mplusready
mui.ready mready
event
组件 触发字符
mui.on(事件绑定) mmon
mui.off(事件取消) mmoff
mui.trigger()(事件触发) mtrigger
mui.fire()(自定义事件) mfire
document.getElementById() dg
document.querySelector() ds
document.querySelector().addEventListener() dsa
document.getElementById().addEventListener() dga
window.addEventListener() wad
document.addEventListener() dad
dialog
组件 触发字符
mui.alert()(弹出框) mdalert
mui.confirm()(确认弹出框) mdconfirm
mui.prompt()(输入弹出框) mdprompt
mui.toast()(自动消失提示框) mdtoast
mui.closePopup()(关闭最外层对话框) mdclosePopup
mui.closePopups()(关闭全部对话框) mdclosePopups
utils
组件 触发字符
mui() (mui对象选择器) mmui
mui.each()(数组,对象遍历) meach
mui().each()(DOM遍历) mmeach
mui.extends(对象合并) mextends
mui.later() (setTimeOut封装) mlater
mui.scrollTo() (滚动到指定位置) mscrollto
mui.os()(判断当前运行环境) mos
ajax
组件 触发字符
mui.ajax() majax
mui.post() mpost
mui.get() mget
mui.getJSON() mjson
webview
组件 触发字符
mui.open(打开新页面) mopen
mui.currentWebview (当前页面) mcurrent
mui.back()(关闭窗口) mback
mui.backFunction()(重写返回逻辑) mbackfunction
mui.backDouble()(双击退出应用) mbackDouble
mui.backTast(双击进入后台) mbacktast
mui.preload()(预加载) mpreload
plus
组件 触发字符
plusReady pready
plus.accelerometer pacce
plus.audio paudio
plus.barcode pbarcode
plus.camera pcamera
plus.contacts pcontacts
plus.device pdevice
plus.gallery pgallery
plus.geolocation pgeolocation
plus.io pio
plus.key pkey
plus.maps pmaps
plus.messaging pmessaging
plus.nativeObj pnativeObj
plus.nativeUI pnativeUI
plus.navigator pnavigator
plus.orientation porientation
plus.payment ppayment
plus.proximity pproximity
plus.push ppush
plus.runtime pruntime
常用代码块
打开一个新的窗口并传值, mui.openWindow():
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
index.html
mui.init(); // mui插件初始化
document.getElementById("setting").addEventListener("tap",function(){
mui.openWindow({
"url":"new.html", // 新页面的html名字
"id":"new.html", // id用于新页面接收原页面的mui.fire而做出响应
styles:{
top:"0px",
bottom:"50px"
}, // 新页面与四周的间距
extras:{
name:"666"
} // extras 用于向新页面传值
});
});
new.html
mui.init();
mui.plusReady(function () {
var Sdata = plus.webview.currentWebview();
console.log(JSON.stringify(Sdata)); // {name:666}
console.log(Sdata.name); // 666
});
打开新窗口并传值 简单示例
触发自定义事件:通过mui.fire()方法可触发目标窗口的自定义事件:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
Document
首页
首页
邮件
设置
mui.init();
mui.plusReady(function () {
})
document.getElementById("setting").addEventListener("tap",function(){
mui.openWindow({
"url":"new.html",
"id":"new.html",
styles:{
top:"0px",
bottom:"50px"
},
extras:{
name:"666"
}
});
});
document.getElementById('email').addEventListener('tap',function () {
var new_page = plus.webview.getWebviewById("new.html");
mui.fire(new_page,'show_alert',{name:"chunsheng"});
})
index.html
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
Document
登录页面
Item 1
Item 2
Item 3
mui.init();
mui.plusReady(function () {
var Sdata = plus.webview.currentWebview();
console.log(JSON.stringify(Sdata));
console.log(Sdata.name); // 666
});
document.addEventListener("show_alert",function(data){
console.log(JSON.stringify(data.detail.name)); // chunsheng
alert("欢迎观临");
}) // 接收到来自 index.html 的 mui.fire 中的show_alert,然后做出响应 alert("欢迎观临")
new.html
mui使用 简单示例(登录功能及主页图文列表显示新闻功能):
后端(使用Flask框架 + MongoDB数据库):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#数据库配置
import pymongo
client = pymongo.MongoClient(host="127.0.0.1",port=27017) # 内部封装 连接池
MONGO_DB = client["day118"] # 连接一个数据库
setting.py
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from flask import Flask, request, jsonify, send_file
from setting import MONGO_DB
app = Flask(__name__)
@app.route("/login",methods=["POST"])
def login():
# username = request.form.get("username")
# password = request.form.get("password")
user_info = request.form.to_dict()
print(user_info)
user = MONGO_DB.users.find_one(user_info)
if user:
return jsonify({"status":200,"msg":f"欢迎{user.get('nickname')}登录"}) # content-type:app/json
else:
return jsonify({"status":201,"msg":"用户名密码错误"})
@app.route("/content_list", methods=["POST"])
def content_list():
res = list(MONGO_DB.content.find({},{"_id":0}))
return jsonify(res)
@app.route("/get_image/")
def get_image(filename):
import os
path = os.path.join("tupian", filename) # tupian目录下放所需图片
return send_file(path)
if __name__ == '__main__':
app.run("0.0.0.0", 9527, debug=True)
app.py
前端(mui框架 + hbuilder):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
Document
首页
首页
电话
邮件
设置
mui.init();
mui.plusReady(function () {
mui.post('http://192.168.13.144:9527/content_list',{
},function(data){
for (var i = 0; i < data.length; i++) {
// console.log(JSON.stringify(data[i]))
create_item(data[i]);
}
},'json'
);
})
document.getElementById('home').addEventListener('tap',function () {
mui.openWindow({
"url":"index.html",
"id":"index.html",
});
})
document.getElementById("setting").addEventListener("tap",function(){
mui.openWindow({
"url":"login_my.html",
"id":"login_my.html",
styles:{
top:"0px",
bottom:"50px"
},
extras:{
}
});
});
function create_item(content){
var li = document.createElement("li");
li.className ="mui-table-view-cell mui-media";
var a = document.createElement("a");
var img = document.createElement("img");
img.className ="mui-media-object mui-pull-left";
img.src = "http://192.168.13.144:9527/get_image/"+content.image;
var div = document.createElement("div");
div.className="mui-media-body";
div.innerText = content.tilte;
var p = document.createElement("p");
p.className="mui-ellipsis";
p.innerText=content.text;
li.appendChild(a);
a.appendChild(img);
a.appendChild(div);
div.appendChild(p);
document.getElementById("content_list").appendChild(li);
}
index.html(主页)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
Document
登录页面
用户名
密码
登录
取消
mui.init();
document.getElementById('login_btn').addEventListener('tap',function () {
var username = document.getElementById("username").value;
var password = document.getElementById("password").value;
mui.post('http://192.168.13.144:9527/login',{
username:username,
password:password
},function(data){
mui.toast(data.msg);
},'json'
);
})
login.html
轮播图功能实现示例(包括每秒自动轮播)--hbuilderx
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
doctype html>
xingfudao_index
预约
mui.init();
// 获取当前文档中轮播图组件对象
var sliderObj = mui('#slider');
// 轮播图每秒自动轮播
sliderObj.slider({
interval:1000
});
轮播图
九宫格功能示例--hbuilderx
注意:通过定义.mui-col-sm-6类在大屏(≥400px)设备上会展现为并排的两列,而.mui-col-xs-12在小屏(<400px)设备上会覆盖之前定义的类展现为水平排列
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
婚纱拍摄
全球旅拍
婚宴酒店
婚礼服务
婚纱拍摄
全球旅拍
婚礼顾问
新人说
九宫格
图文列表功能示例--hbuilderx
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
;
婚宴酒店
更多;
【巴厘岛】乌干沙悦榕庄酒店 白羽教堂
周一到周日 | 提前3天预约
¥42888.0
门店价:¥42888
售出:6
【苏梅岛】班达灵岩洲际度假村 沙滩
周一到周日 | 提前3天预约
¥31999.0
门店价:¥31999
售出:8
【冲绳】乌干沙悦榕庄酒店 白羽教堂
周一到周日 | 提前3天预约
¥42888.0
门店价:¥42888
售出:10
【巴厘岛】乌干沙悦榕庄酒店 白羽教堂
周一到周日 | 提前3天预约
¥42888.0
门店价:¥42888.0
售出:2
【巴厘岛】乌干沙悦榕庄酒店 白羽教堂
周一到周日 | 提前3天预约
¥42888.0
门店价:¥42888.0
售出:2
图文列表
底部选项卡功能示例(包括点击切换页面)--hbuilderx
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
DOCTYPE html>
.mui-active .mui-icon,.mui-active .mui-tab-label{
color:deeppink;
}
首页
通讯录
h5plus
我的
mui.init();
//实现底部选项卡切换功能
mui.plusReady(function () {
//定义一个容器,用于存储底部选项卡所关联的页面
var pages = ["xingfudao_index.html","xingfudao_contact.html","xingfudao_h5plus.html","xingfudao_wode.html"];
//获取当前窗口对象
var ws = plus.webview.currentWebview();
//设置页面窗口样式,给底部选项卡留50px高度
var pageStyle = {
top:"0px",
bottom:"50px"
};
//循环数组,为每个页面创建webview窗口对象
for(var i = 0;i 选项 -> HBuilder -> 第三方Android模拟器端口改为 62001,然后确定,可以看到左下角提示:手机127.0.0.1:62001已连接上电脑
![](https://img2018.cnblogs.com/common/1545867/202001/1545867-20200117181036020-1012575061.png)
4.在hbuilder中 选择 在手机设备上运行或停止应用,选择第一个:hbuilder基座运行 ,然后会自动在夜神模拟器上安装手机端hbuilder
![](https://img2018.cnblogs.com/common/1545867/202001/1545867-20200117180809795-285112055.png)
![](https://img2018.cnblogs.com/common/1545867/202001/1545867-20200117181723076-1141352733.png)
其他调试方式,例如真机测试请参考网上http://ask.dcloud.net.cn/article/69
hbuilder app打包流程:
首先得登录HBuilder,然后再打包
![](https://img2018.cnblogs.com/common/1545867/202002/1545867-20200207000035075-1425657801.png)
![](https://img2018.cnblogs.com/common/1545867/202002/1545867-20200207000054692-294292109.png)
![](https://img2018.cnblogs.com/common/1545867/202002/1545867-20200207000120968-2065180789.png)
![](https://img2018.cnblogs.com/common/1545867/202002/1545867-20200207000138091-1575666186.png)
![](https://img2018.cnblogs.com/common/1545867/202002/1545867-20200207000154957-993562581.png)
![](https://img2018.cnblogs.com/common/1545867/202002/1545867-20200207000219101-256446800.png)
![](https://img2018.cnblogs.com/common/1545867/202002/1545867-20200207000255837-1859805159.png)
![](https://img2018.cnblogs.com/common/1545867/202002/1545867-20200207000311628-294277913.png)
![](https://img2018.cnblogs.com/common/1545867/202002/1545867-20200207000327788-1447743900.png)
返回顶部
|