首页 > 其他分享 >Flask 与 HTML5 简单功能实现

Flask 与 HTML5 简单功能实现

时间:2023-04-09 17:35:41浏览次数:44  
标签:function Flask mui html user 简单 document data HTML5

Flask 与 HTML5 简单功能实现

目录

1 实现注册与登陆

1.1 前端配置

  • 使用HBuilder X创建mui项目
<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8" />
	<title>Document</title>
	<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
	<link rel="stylesheet" type="text/css" href="css/mui.css"/>
</head>
<body>
	<header class="mui-bar mui-bar-nav">
		<a class="mui-action-back mui-icon mui-icon-left-nav mui-pull-left"></a>
		<h1 class="mui-title">phone page</h1>
	</header>
	<div class="mui-content">
		<form class="mui-input-group">
			<div class="mui-input-row">
				<label>用户名:</label>
				<input type="text" class="mui-input-clear" id='username' value="user01">
			</div>
			<div class="mui-input-row">
				<label>密码:</label>
			<input type="password" class="mui-input-clear" id='password' value="1234">
			</div>
			<div class="mui-input-row">
				<label>男:</label>
				<input name='gender' type="radio" value="1" checked>
			</div>
			<div class="mui-input-row">
				<label>女:</label>
				<input name='gender' type="radio" value="2">
			</div>
		<button type="button" class="mui-btn mui-btn-red mui-btn-block" id='cmr-btn'>开始拍照</button>
		</form>
		
		<form class="mui-input-group">
			<div class="mui-input-row">
				<label>用户名:</label>
				<input type="text" class="mui-input-clear" id='user' value="user01">
			</div>
			<div class="mui-input-row">
				<label>密码:</label>
			<input type="password" class="mui-input-clear" id='passwd' value="1234">
			</div>
			<div class="mui-input-row">
			<button type="button" class="mui-btn mui-btn-green mui-btn-block" id='submit'>登录</button>
			</div>
		</form>
		<div class="mui-input-row" style="text-align: center;">
		<img id="cmr-pic" style="width: 150px; height: 150px; border-radius: 50%;">
		</div>
		
	</div>
	<script src="js/mui.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		// 扩展API加载完毕后调用onPlusReady回调函数 
		document.addEventListener( "plusready", onPlusReady, false );
		// 扩展API加载完毕,现在可以正常调用扩展API 
		function onPlusReady() {
			console.log("plusready");
		};
		mui.init();
		mui.back = function(){};
		// 拍照
		document.getElementById('cmr-btn').addEventListener('tap',function () {
			var username = document.getElementById("username").value;
			var password = document.getElementById("password").value;
			var gender_list = document.getElementsByName('gender');
		   mui.toast('开启摄像头');
		   var cmr = plus.camera.getCamera(); 
		   var res = cmr.supportedImageResolutions[30];
		   var fmt = cmr.supportedImageFormats[0];
		   
		   console.log("Resolution: "+res+", Format: "+fmt);
		   cmr.captureImage( function( path ){
					mui.toast( "Capture image success: " + path );
					// console.log(path);
					var task = plus.uploader.createUpload( "http://192.168.50.117:5000/upload",
						{ method:"POST",priority:100 },
						function ( t, status ) {
							// 上传完成
							if ( status == 200 ) { 
								alert( "Upload success: " + t.url );
							} else {
								alert( "Upload failed: " + status );
							}
						}
					);
					task.addFile( path, {key:"jpg"} );
					task.addData( "username", username );
					task.addData( "password", password );
					for (var i = 0; i<gender_list.length; i++) {
						if (gender_list[i].checked) {
							var gender = gender_list[i].value;
						}
					}
					task.addData( "gender", gender );
					
					//task.addEventListener( "statechanged", onStateChanged, false );
					task.start();
				},
				function( error ) {
					mui.toast( "Capture image failed: " + error.message );
				},
				// options
				{
					filename:'_doc/fcarey/a.jpg',
					resolution:res,
					format:fmt,
				},
			);
	});
	document.getElementById('submit').addEventListener('tap',function () {
	        var user = document.getElementById('user').value;
	        var passwd = document.getElementById('passwd').value;
			mui.post(
				'http://192.168.50.117:5000/login',{
					'username':user,
					'password':passwd,
				},function(data){
				console.log(JSON.stringify(data.data.avatar));
				document.getElementById("cmr-pic").src = 'http://192.168.50.117:5000/get_avatar/'+data.data.avatar;
				alert(data.msg);
			},'json'
			);
	});
	</script>
</body>
</html>

1.2 后端配置

from flask import Flask, request, jsonify, send_file
from pymongo import MongoClient

app = Flask(__name__)
app.debug = True
MC = MongoClient(host='127.0.0.1', port=27017)
db = MC['fcarey01']


@app.route('/upload', methods=['post'])
def upload():
    user_info = request.form.to_dict()
    file = request.files.get('jpg')
    file.save(user_info.get('username') + '.jpg')
    user_info['avatar'] = user_info.get('username') + '.jpg'
    res = db.members.insert_one(user_info)
    if res.inserted_id:
        return f"恭喜{user_info.get('username')}用户,注册成功!"
    else:
        return 'out'


@app.route('/login', methods=['post'])
def login():
    user_info = request.form.to_dict()
    user = db.members.find_one(user_info)
    print(user)
    if user:
        user['_id'] = str(user.get('_id'))  # 将ObjectId转换为字符串
        return jsonify({"code": 0, "msg": "登录成功", "data": user})
    else:
        return jsonify({"code": 1, "msg": "登录失败"})


@app.route('/get_avatar/<filename>')
def get_avatar(filename):
    return send_file(filename)


if __name__ == '__main__':
    app.run(host='192.168.50.117', port=5000)

2 flask 与 html5+

实现:

  1. 打开展示首页
  2. 用户注册
  3. 用户登陆,并跳转至user_info.html页面
  4. 利用html5+操作设备:控制本地/远程音乐播放、震动

1.1 前端配置

  1. 使用HBuilder X创建mui项目

1.1.1index.html配置

<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8" />
	<title>Document</title>
	<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
	<link rel="stylesheet" type="text/css" href="css/mui.css"/>
</head>
<body>
	<header class="mui-bar mui-bar-nav">
		<h1 class="mui-title">首页</h1>
	</header>
	<div class="mui-content">
		it's index.html.
	</div>
	<nav class="mui-bar mui-bar-tab">
		<a class="mui-tab-item mui-active" id='home'>
			<span class="mui-icon mui-icon-home"></span>
			<span class="mui-tab-label">首页</span>
		</a>
		<a class="mui-tab-item" id='register'>
			<span class="mui-icon mui-icon-phone"></span>
			<span class="mui-tab-label">电话</span>
		</a>
		<a class="mui-tab-item" id="audio">
			<span class="mui-icon mui-icon-mic"></span>
			<span class="mui-tab-label">语音</span>
		</a>
		<a class="mui-tab-item" id="login">
			<span class="mui-icon mui-icon-gear"></span>
			<span class="mui-tab-label">登录</span>
		</a>
	</nav>
	<script src="js/mui.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">

	mui.init({
	  gestureConfig:{
	   tap: true, //默认为true
	   doubletap: true, //默认为false
	   longtap: true, //默认为false
	   swipe: true, //默认为true
	   drag: true, //默认为true
	   hold:false,//默认为false,不监听
	   release:false,//默认为false,不监听
	   },
	   subpages:[{
	     url:'main.html',//子页面HTML地址,支持本地地址和网络地址
	     id:'main.html',//子页面标志
	     styles:{
	       top:'0px',//子页面顶部位置
	       bottom:'50px',//子页面底部位置
	     },
	     extras:{}//额外扩展参数
	   }]
	});
	document.getElementById('home').addEventListener('tap',function () {
	  mui.openWindow({
		url: 'main.html', 
		id:'main.html',
		styles:{
		  top:'0px',//子页面顶部位置
		  bottom:'50px',//子页面底部位置
		},
	  });
	  var index_webview = plus.webview.currentWebview();
	  console.log(JSON.stringify(index_webview));
	  
	});
	document.getElementById('register').addEventListener('tap',function () {
	  mui.openWindow({
		url: 'register.html', 
		id:'register.html',
		styles:{
		       top:'0px',//新页面顶部位置
		       bottom:'50px',//新页面底部位置
		     },
	  });
	});
	document.getElementById('audio').addEventListener('tap',function () {
	  mui.openWindow({
		url: 'audio.html', 
		id:'audio.html',
		styles:{
		       top:'0px',//新页面顶部位置
		       bottom:'50px',//新页面底部位置
		},
		extras:{
			username:'fcarey',
		},
		createNew:true,
	  });
	});
	document.getElementById('login').addEventListener('tap',function () {
	  if (plus.storage.getItem('user_id')) {
			mui.openWindow({
					url: 'user_info.html', 
					id:'user_info.html',
					styles:{
						   top:'0px',//新页面顶部位置
						   bottom:'50px',//新页面底部位置
						 },
			});
	  } else{
	  	mui.openWindow({
	  			url: 'login.html', 
	  			id:'login.html',
	  			styles:{
	  				   top:'0px',//新页面顶部位置
	  				   bottom:'50px',//新页面底部位置
	  				 },
	  	});
	  }
	});
	</script>
</body>
</html>

1.1.2 main.html配置

<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8" />
	<title>Document</title>
	<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
	<link rel="stylesheet" type="text/css" href="css/mui.css"/>
</head>
<body>
	<header class="mui-bar mui-bar-nav">
		<h1 class="mui-title">标题</h1>
	</header>
	<div class="mui-content">
		it's main.html
	</div>
	<script src="js/mui.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
	mui.init()
	</script>
</body>
</html>

1.1.3 register.html配置

<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8" />
	<title>Document</title>
	<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
	<link rel="stylesheet" type="text/css" href="css/mui.css"/>
</head>
<body>
	<header class="mui-bar mui-bar-nav">
		<a class="mui-action-back mui-icon mui-icon-left-nav mui-pull-left"></a>
		<h1 class="mui-title">register</h1>
	</header>
	<div class="mui-content">
		<form class="mui-input-group">
			<div class="mui-input-row">
				<label>用户名:</label>
				<input type="text" class="mui-input-clear" id='username' value="user01">
			</div>
			<div class="mui-input-row">
				<label>密码:</label>
			<input type="password" class="mui-input-clear" id='password' value="1234">
			</div>
			<div class="mui-input-row">
				<label>男:</label>
				<input name='gender' type="radio" value="1" checked>
			</div>
			<div class="mui-input-row">
				<label>女:</label>
				<input name='gender' type="radio" value="2">
			</div>
		<button type="button" class="mui-btn mui-btn-red mui-btn-block" id='cmr-btn'>开始拍照</button>
		</form>
		
		<form class="mui-input-group">
			<div class="mui-input-row">
				<label>用户名:</label>
				<input type="text" class="mui-input-clear" id='user' value="user01">
			</div>
			<div class="mui-input-row">
				<label>密码:</label>
			<input type="password" class="mui-input-clear" id='passwd' value="1234">
			</div>
			<div class="mui-input-row">
			<button type="button" class="mui-btn mui-btn-green mui-btn-block" id='submit'>登录</button>
			</div>
		</form>
		<div class="mui-input-row" style="text-align: center;">
		<img id="cmr-pic" style="width: 150px; height: 150px; border-radius: 50%;">
		</div>
		
	</div>
	<script src="js/mui.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		// 扩展API加载完毕后调用onPlusReady回调函数 
		document.addEventListener( "plusready", onPlusReady, false );
		// 扩展API加载完毕,现在可以正常调用扩展API 
		function onPlusReady() {
			console.log("plusready");
		};
		mui.init();
		mui.back = function(){};
		// 拍照
		document.getElementById('cmr-btn').addEventListener('tap',function () {
			var username = document.getElementById("username").value;
			var password = document.getElementById("password").value;
			var gender_list = document.getElementsByName('gender');
		   mui.toast('开启摄像头');
		   var cmr = plus.camera.getCamera(); 
		   var res = cmr.supportedImageResolutions[30];
		   var fmt = cmr.supportedImageFormats[0];
		   
		   console.log("Resolution: "+res+", Format: "+fmt);
		   cmr.captureImage( function( path ){
					mui.toast( "Capture image success: " + path );
					// console.log(path);
					var task = plus.uploader.createUpload( "http://192.168.50.117:5000/upload",
						{ method:"POST",priority:100 },
						function ( t, status ) {
							// 上传完成
							if ( status == 200 ) { 
								alert( "Upload success: " + t.url );
							} else {
								alert( "Upload failed: " + status );
							}
						}
					);
					task.addFile( path, {key:"jpg"} );
					task.addData( "username", username );
					task.addData( "password", password );
					for (var i = 0; i<gender_list.length; i++) {
						if (gender_list[i].checked) {
							var gender = gender_list[i].value;
						}
					}
					task.addData( "gender", gender );
					
					//task.addEventListener( "statechanged", onStateChanged, false );
					task.start();
				},
				function( error ) {
					mui.toast( "Capture image failed: " + error.message );
				},
				// options
				{
					filename:'_doc/fcarey/a.jpg',
					resolution:res,
					format:fmt,
				},
			);
	});
	document.getElementById('submit').addEventListener('tap',function () {
	        var user = document.getElementById('user').value;
	        var passwd = document.getElementById('passwd').value;
			mui.post(
				'http://192.168.50.117:5000/login',{
					'username':user,
					'password':passwd,
				},function(data){
				console.log(JSON.stringify(data.data.avatar));
				document.getElementById("cmr-pic").src = 'http://192.168.50.117:5000/get_avatar/'+data.data.avatar;
				alert(data.msg);
			},'json'
			);
	});
	</script>
</body>
</html>

1.1.4 login.html配置

<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8" />
	<title>Document</title>
	<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
	<link rel="stylesheet" type="text/css" href="css/mui.css"/>
</head>
<body>
	<header class="mui-bar mui-bar-nav">
		<h1 class="mui-title">用户登录</h1>
	</header>
	<div class="mui-content">
		<form class="mui-input-group">
			<div class="mui-input-row">
		        <label>用户名</label>
		    <input type="text" id="username" class="mui-input-clear" value="user01">
		    </div>
		    <div class="mui-input-row">
		        <label>密码</label>
		        <input type="password" id="password" class="mui-input-password" value="1234">
		    </div>
		    <div class="mui-button-row">
		        <button type="button" class="mui-btn mui-btn-primary"  id="loginBtn">登录</button>
		        <button type="button" class="mui-btn mui-btn-danger" >取消</button>
		    </div>
		</form>
	</div>
	<script src="js/mui.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
	mui.init()
	document.getElementById('loginBtn').addEventListener('tap',function () {
		var username = document.getElementById("username").value;
		var password = document.getElementById("password").value;
	        mui.post("http://192.168.50.117/login",{
	        		'username':username,
					'password':password,
	        	},function(data){
	        		console.log(JSON.stringify(data))
					if (data.code == 0) {
						plus.storage.setItem('user_id',data.data._id);
						mui.toast(data.msg);
						mui.openWindow({
						  url:'user_info.html',//子页面HTML地址,支持本地地址和网络地址
						  id:'user_info.html',//子页面标志
						  styles:{
							top:'0px',//子页面顶部位置
							bottom:'50px',//子页面底部位置
						  },
						  extras:data.data,//额外扩展参数
						  createNew:true,
						});
					} else{
						mui.toast(data.msg);
					}
	        	},'json'
	        );
	})
	document.addEventListener('sayByebye',function(data){
		console.log(JSON.stringify(data.detail));
		mui.toast("再见"+data.detail.username);
	});
	</script>
</body>
</html>

1.1.5 user_info.html配置

<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8" />
	<title>Document</title>
	<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
	<link rel="stylesheet" type="text/css" href="css/mui.css"/>
</head>
<body>
	<header class="mui-bar mui-bar-nav">
		<h1 class="mui-title" id="userinfo">用户详情</h1>
	</header>
	<div class="mui-content">
		用户详情
	</div>
	<div class="mui-content">
		<button type="button" class="mui-btn mui-btn-blue mui-btn-block" id="logout">退出</button>
	</div>
	<script src="js/mui.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
	mui.init();
	// 扩展API加载完毕后调用onPlusReady回调函数
	document.addEventListener( "plusready", onPlusReady, false );
	// 扩展API加载完毕,现在可以正常调用扩展API 
	function onPlusReady() { 
		var wv = plus.webview.currentWebview();
		document.getElementById('userinfo').innerText = wv.username;
		
		var wv_opener = wv.opener();
		console.log(wv_opener.id);
		if (wv_opener.id == 'login.html') {
			var login_wv = plus.webview.getWebviewById('login.html');
			login_wv.hide();
			login_wv.close();
		} else{
			
		}
	};
	document.getElementById('logout').addEventListener('tap',function () {
	        plus.storage.removeItem('user_id');
			mui.openWindow({
			url:'login.html',
			id: 'login.html',
			styles:{
				top:'0px',//子页面顶部位置
				bottom:'50px',//子页面底部位置
			},
			});
			var index = plus.webview.getWebviewById("login.html"); // index页面id为HBuilder
			mui.fire(index, 'sayByebye',{"username":"fcarey"});
	});
	

	</script>
</body>
</html>

1.1.6 audio.html

<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8" />
	<title>Document</title>
	<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
	<link rel="stylesheet" type="text/css" href="css/mui.css"/>
</head>
<body>
	<header class="mui-bar mui-bar-nav">
		<h1 class="mui-title" id='title'>audio</h1>
	</header>
	<div class="mui-content">
		<button type="button" class="mui-btn mui-btn-blue mui-btn-block" id='player'> 播放</button>	
		<button type="button" class="mui-btn mui-btn-yellow mui-btn-block" id='player_pause'>暂停</button>	
		<button type="button" class="mui-btn mui-btn-green mui-btn-block" id='player_resume'>恢复</button>	
		<button type="button" class="mui-btn mui-btn-red mui-btn-block" id='player_stop'>结束</button>	
	</div>
	<div class="mui-content">
		<button type="button" class="mui-btn mui-btn-blue mui-btn-block" id='recoder'>录音</button>	
	</div>
	<div class="mui-content">
		<button type="button" class="mui-btn mui-btn-red mui-btn-block" id='vibrate'>震动</button>	
	</div>
	<div class="mui-content">
		<audio id="audio_player"></audio>
	</div>
	<script src="js/mui.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
	mui.init({
	  	gestureConfig:{
		   tap: true, 
		   doubletap: true, 
		   longtap: true, 
		   swipe: true, 
		   drag: true, 
		   hold:true,
		   release:true
	  	},

	});
	// 扩展API加载完毕后调用onPlusReady回调函数 
	document.addEventListener( "plusready", onPlusReady, false );
	// 扩展API加载完毕,现在可以正常调用扩展API 
	function onPlusReady() { 
		var wv = plus.webview.currentWebview();
		console.log(JSON.stringify(wv));
		document.getElementById("title").innerText=wv.username;
	}
	var p = null; 
	document.getElementById('player').addEventListener('tap',function () {
		console.log(plus.os.name)
		if(plus.os.name == "Android"){
			p = plus.audio.createPlayer('https://aod.cos.tx.xmcdn.com/storages/3a46-audiofreehighqps/4F/1D/GKwRIasH-al8ABnBggIIQJ7--aacv2-48K.m4a');
			if ( plus.audio == undefined ) {
				alert( "Device not ready!" );
			}
			else {
				p.play( function () {
					alert( "Audio play success!" ); 
				}, function ( e ) {
					alert( "Audio play error: " + e.message ); 
				} ); 
			}
		}else{
			//解决 iOS 无法远程播放音频
			console.log("iOS");
			p = document.getElementById("audio_player");
			p.src = 'https://aod.cos.tx.xmcdn.com/storages/3a46-audiofreehighqps/4F/1D/GKwRIasH-al8ABnBggIIQJ7--aacv2-48K.m4a';
			p.play();
		}

	});
	document.getElementById('player_pause').addEventListener('tap',function () {
		p.pause();
	});
	document.getElementById('player_resume').addEventListener('tap',function () {
		p.resume();
	});
	document.getElementById('player_stop').addEventListener('tap',function () {
		p.stop();
	});
	document.getElementById('player_stop').addEventListener('tap',function () {
		p.stop();
	});
	var r = null;
	document.getElementById('recoder').addEventListener('hold',function () {
		r = plus.audio.getRecorder();
		r.record({filename:'_doc/recoders/'},function (path) {
			mui.toast(path+'录音完成');
			createUpload(path)
		},function (e) {
			mui.toast("Audio record failed: " + e.message);
		});
	});
	document.getElementById('recoder').addEventListener('release',function () {
		r.stop();
	});
	// 创建上传任务
	function createUpload(path) {
		var task = plus.uploader.createUpload( "http://192.168.50.117/uploader", 
			{ method:"POST",priority:100 },
			function ( t, status ) {
				// 上传完成
				if ( status == 200 ) { 
					console.log( JSON.stringify(t) );
					console.log( t.responseText );
				} else {
					alert( "Upload failed: " + status );
				}
			}
		);
		task.addFile( path, {key:'recoder'} );
		task.addData( "name", "recoder01.amr" );
		//task.addEventListener( "statechanged", onStateChanged, false );
		task.start();
	};
	
	document.getElementById('vibrate').addEventListener('tap',function () {
	        // var v = plus.device.vibrate(500)
	});

	</script>
</body>
</html>

2.1 后端配置

app.py

from flask import Flask, request, jsonify, send_file
from pymongo import MongoClient

app = Flask(__name__)
app.debug = True
MC = MongoClient(host='127.0.0.1', port=27017)
db = MC['fcarey01']


@app.route('/upload', methods=['post'])
def upload():
    user_info = request.form.to_dict()
    file = request.files.get('jpg')
    file.save(user_info.get('username') + '.jpg')
    user_info['avatar'] = user_info.get('username') + '.jpg'
    res = db.members.insert_one(user_info)
    if res.inserted_id:
        return f"恭喜{user_info.get('username')}用户,注册成功!"
    else:
        return 'out'


@app.route('/login', methods=['post'])
def login():
    user_info = request.form.to_dict()
    user = db.members.find_one(user_info)
    print(user)
    if user:
        user['_id'] = str(user.get('_id'))  # 将ObjectId转换为字符串
        return jsonify({"code": 0, "msg": "登录成功", "data": user})
    else:
        return jsonify({"code": 1, "msg": "登录失败"})


@app.route('/get_avatar/<filename>')
def get_avatar(filename):
    return send_file(filename)


if __name__ == '__main__':
    app.run(host='192.168.50.117', port=5000)

3 实现语音发送功能

  • 用户发送语音
  • 接收端接收语音并播放

3.1 前端配置

  1. 使用HBuilder X创建mui项目

3.1.1index.html配置

<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8" />
	<title>Document</title>
	<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
	<link rel="stylesheet" type="text/css" href="css/mui.css"/>
</head>
<body>
	<header class="mui-bar mui-bar-nav">
		<h1 class="mui-title">首页</h1>
	</header>
	<div class="mui-content">
		it's index.html.
	</div>
	<nav class="mui-bar mui-bar-tab">
		<a class="mui-tab-item mui-active" id='home'>
			<span class="mui-icon mui-icon-home"></span>
			<span class="mui-tab-label">首页</span>
		</a>
		<a class="mui-tab-item" id='phone'>
			<span class="mui-icon mui-icon-phone"></span>
			<span class="mui-tab-label">电话</span>
		</a>
		<a class="mui-tab-item" id="message">
			<span class="mui-icon mui-icon-mic"></span>
			<span class="mui-tab-label">语音</span>
		</a>
		<a class="mui-tab-item" id="login">
			<span class="mui-icon mui-icon-gear"></span>
			<span class="mui-tab-label">登录</span>
		</a>
	</nav>
	<script src="js/mui.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">

	mui.init();
	// 扩展API加载完毕后调用onPlusReady回调函数
	document.addEventListener( "plusready", onPlusReady, false );
	// 扩展API加载完毕,现在可以正常调用扩展API 
	function onPlusReady() { 
		var main_wv = plus.webview.create(
		'main.html',
		'main.html',
		{
			top:'0px',//新页面顶部位置
			bottom:'50px',//新页面底部位置
		});
		main_wv.show();
		document.addEventListener('app_create_ws',function(data){
			ws = new WebSocket(window.ws_serv + data.detail._id);
		});
		document.addEventListener('ws_send_data',function(data){
			var send_data = JSON.stringify(data.detail);
			ws.send(send_data);
		});
	};
	document.getElementById('home').addEventListener('tap',function () {
	        mui.openWindow({
	        		url: 'main.html', 
	        		id:'main.html',
	        		styles:{
	        		       top:'0px',//新页面顶部位置
	        		       bottom:'50px',//新页面底部位置
	        		     },
	        });
	});
	document.getElementById('message').addEventListener('tap',function () {
	        mui.openWindow({
	        		url: 'message.html', 
	        		id:'message.html',
	        		styles:{
	        		       top:'0px',//新页面顶部位置
	        		       bottom:'50px',//新页面底部位置
	        		     },
	        });
	});
	document.getElementById('login').addEventListener('tap',function () {
	  mui.openWindow({
	  		url: 'login.html', 
	  		id:'login.html',
	  		styles:{
	  			   top:'0px',//新页面顶部位置
	  			   bottom:'50px',//新页面底部位置
	  			 },
	  });
	})	
	</script>
</body>
</html>

3.1.2 main.html

<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8" />
	<title>Document</title>
	<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
	<link rel="stylesheet" type="text/css" href="css/mui.css"/>
</head>
<body>
	<header class="mui-bar mui-bar-nav">
		<h1 class="mui-title">标题</h1>
	</header>
	<div class="mui-content">
		<div id="slider" class="mui-slider" >
		  <div class="mui-slider-group mui-slider-loop">
			<!-- 额外增加的一个节点(循环轮播:第一个节点是最后一张轮播) -->
			<div class="mui-slider-item mui-slider-item-duplicate">
				
			  <a href="#">
				<img src="http:\/\/placehold.it\/400x300">
			  </a>
			  
			</div>
			<!-- 第一张 -->
			<div class="mui-slider-item">
			  <a href="#">
				<img src="http:\/\/placehold.it\/400x300">
			  </a>
			</div>
			
			<!-- 第二张 -->
			<div class="mui-slider-item">
			  <a href="#">
				  
				<img src="">
				
			  </a>
			</div>
			<!-- 第三张 -->
			<div class="mui-slider-item">
			  <a href="#">
				<img src="">
			  </a>
			</div>
			<!-- 第四张 -->
			<div class="mui-slider-item">
			  <a href="#">
				<img src="http:\/\/placehold.it\/400x300">
			  </a>
			</div>
			<!-- 额外增加的一个节点(循环轮播:最后一个节点是第一张轮播) -->
			<div class="mui-slider-item mui-slider-item-duplicate">
			  <a href="#">
				<img src="http:\/\/placehold.it\/400x300">
			  </a>
			</div>
		  </div>
		  <div class="mui-slider-indicator">
			<div class="mui-indicator mui-active"></div>
			<div class="mui-indicator"></div>
			<div class="mui-indicator"></div>
			<div class="mui-indicator"></div>
		  </div>
		</div>
		
		<ul class="mui-table-view mui-grid-view mui-grid-9">
		<li class="mui-table-view-cell mui-media mui-col-xs-4 mui-col-sm-3">
			<a href="#">
				<span class="mui-icon mui-icon-home"></span>
				<div class="mui-media-body">Home</div>
			</a>
		</li>
		<li class="mui-table-view-cell mui-media mui-col-xs-4 mui-col-sm-3">
			<a href="#">
				<span class="mui-icon mui-icon-email"><span class="mui-badge mui-badge-red">5</span></span>
				<div class="mui-media-body">Email</div>
			</a>
		</li>
		<li class="mui-table-view-cell mui-media mui-col-xs-4 mui-col-sm-3">
			<a href="#">
				<span class="mui-icon mui-icon-chatbubble"></span>
				<div class="mui-media-body">Chat</div>
			</a>
		</li>
		<li class="mui-table-view-cell mui-media mui-col-xs-4 mui-col-sm-3">
			<a href="#">
				<span class="mui-icon mui-icon-location"></span>
				<div class="mui-media-body">Location</div>
			</a>
		</li>
		<li class="mui-table-view-cell mui-media mui-col-xs-4 mui-col-sm-3">
			<a href="#">
				<span class="mui-icon mui-icon-search"></span>
				<div class="mui-media-body">Search</div>
			</a>
		</li>
		<li class="mui-table-view-cell mui-media mui-col-xs-4 mui-col-sm-3">
			<a href="#">
				<span class="mui-icon mui-icon-phone"></span>
				<div class="mui-media-body">Phone</div>
			</a>
		</li>
			</ul>
		
		<ul class="mui-table-view">
			<li class="mui-table-view-cell mui-media">
				<a href="javascript:;">
					<img class="mui-media-object mui-pull-left" src="">
					<div class="mui-media-body">
						幸福
						<p class="mui-ellipsis">能和心爱的人一起睡觉,是件幸福的事情;可是,打呼噜怎么办?</p>
					</div>
				</a>
			</li>
			<li class="mui-table-view-cell mui-media">
				<a href="javascript:;">
					<img class="mui-media-object mui-pull-left" src="">
					<div class="mui-media-body">
						木屋
						<p class="mui-ellipsis">想要这样一间小木屋,夏天挫冰吃瓜,冬天围炉取暖.</p>
					</div>
				</a>
			</li>
			<li class="mui-table-view-cell mui-media">
				<a href="javascript:;">
					<img class="mui-media-object mui-pull-left" src="">
					<div class="mui-media-body">
					    CBD
						<p class="mui-ellipsis">烤炉模式的城,到黄昏,如同打翻的调色盘一般.</p>
					</div>
				</a>
			</li>
		</ul>
		
	</div>
	<script src="js/mui.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
	mui.init()
	</script>
</body>
</html>

3.1.3 message

<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8" />
	<title>Document</title>
	<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
	<link rel="stylesheet" type="text/css" href="css/mui.css"/>
</head>
<body>
	<header class="mui-bar mui-bar-nav">
		<h1 class="mui-title">请说话</h1>
	</header>
	<div class="mui-content">
		
	</div>
	<nav class="mui-bar mui-bar-tab">
		<a class="mui-tab-item" id="speech">
			<span class="mui-icon mui-icon-speech"></span>
			<span class="mui-tab-label">按住说话</span>
		</a>
	</nav>
	<script src="js/mui.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
	mui.init({
	  	gestureConfig:{
		   hold:true,
		   release:true
	  	}
	});
	// 扩展API加载完毕后调用onPlusReady回调函数
	document.addEventListener( "plusready", onPlusReady, false );
	// 扩展API加载完毕,现在可以正常调用扩展API 
	function onPlusReady() { 
		
	};
	var reco = null;
	document.getElementById('speech').addEventListener('hold',function () {
	        reco = plus.audio.getRecorder();
			reco.record({filename:"_doc/voice/",format:"amr"},function(file_path){
				// console.log(file_path);
				createUpload(file_path);
			});
	});
	document.getElementById('speech').addEventListener('release',function () {
	        reco.stop();
	})
	// 创建上传任务
	function createUpload(path) {
		var task = plus.uploader.createUpload( window.serv+"uploader", 
			{ method:"POST",priority:100 },
			function ( t, status ) {
				var wv = plus.webview.currentWebview();
				// 上传完成
				if ( status == 200 ) { 
					ret_json = JSON.parse(t.responseText);//responseText 上完成之后的返回值 String类型 一定要记得转换成Object(json)
					filename = ret_json.data.filename;
					var ws_send_data = {
						msg:filename,
						sender:"app",
						receiver:"receiver"
					}
					var index = plus.webview.getWebviewById("HBuilder");
					mui.fire(index,'ws_send_data', ws_send_data)
				} else {
					alert( "Upload failed: " + status );
				}
			}
		);
		task.addFile( path, {key:'msg'} );
		task.start();
	};
	
	
	</script>
</body>
</html>

3.2 接收端配置

  • templates/ws_client.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>hello</title>
</head>
<body>
<audio controls autoplay id="player"></audio>

<script type="application/javascript">
    var ws = new WebSocket('ws://172.20.10.3:81/app/receiver')
    ws.onmessage = function (data) {
        var data_json = JSON.parse(data.data);
        // console.log(JSON.stringify(data_json));
        document.getElementById('player').src='http://127.0.0.1/get_chat/'+data_json.msg;
    }
</script>
</body>
</html>

3.3 后端设置

3.3.1 setting.py配置

# 数据库配置信息
from pymongo import MongoClient

MC = MongoClient(host='127.0.0.1', port=27017)
MongoDB = MC['fcarey01']

# Return Info 配置
RET = {
    "code": 0,
    "msg": "",
    "data": {}
}

3.3.2 serv/users.pyBluePrint配置

from flask import Blueprint, request, jsonify

from setting import MongoDB, RET

user_bp = Blueprint("user_bp", __name__)


@user_bp.route("/register", methods=["POST"])
def register():
    # 获取FormData中的数据
    user_info = request.form.to_dict()
    # 将数据转换成字典 直接存放在MongoDB中
    res = MongoDB.users.insert_one(user_info)
    if res.inserted_id:
        RET["code"] = 0
        RET["msg"] = "注册成功"
        RET["data"] = {}
        return jsonify(RET)
    else:
        RET["code"] = 1
        RET["msg"] = "注册失败"
        RET["data"] = {}
        return jsonify(RET)


@user_bp.route("/login", methods=["POST"])
def login():
    login_info = request.form.to_dict()
    user_info = MongoDB.members.find_one(login_info)
    print(login_info)
    if not user_info:
        # 登录失败
        RET["code"] = 1
        RET["msg"] = "用户名密码错误"
        RET["data"] = {}

        return jsonify(RET)
    else:
        user_info["_id"] = str(user_info.get("_id"))
        user_info.pop("password")  # 删除敏感字段

        RET["code"] = 0
        RET["msg"] = "登录成功"
        RET["data"] = user_info

        return jsonify(RET)

3.3.3 serv/upload.pyBluePrint配置

import os
from flask import Blueprint, request, jsonify, send_file
from setting import MongoDB, RET

upload = Blueprint("upload", __name__)


@upload.route("/uploader", methods=["POST"])
def uploader():
    reco = request.files.get("msg")  # FileStorage
    reco.save(reco.filename)
    os.system(f"ffmpeg -i {reco.filename} {reco.filename}.mp3")
    RET["code"] = 0
    RET["msg"] = "上传成功"
    RET["data"] = {"filename": f"{reco.filename}.mp3"}

    return jsonify(RET)


@upload.route("/get_chat/<filename>")
def get_chat(filename):
    print(filename)
    return send_file(filename)

3.3.4 app.py配置

from flask import Flask, render_template
from serv.users import user_bp
from serv.upload import upload
from flask_cors import CORS

app = Flask(__name__)
CORS(app=app)
app.config['DEBUG'] = True
app.register_blueprint(user_bp)
app.register_blueprint(upload)


# 创建 reciver 页面
@app.route('/')
def index():
    # return '200 ok'
    return render_template('ws_client.html')


if __name__ == '__main__':
    app.run('0.0.0.0', 80)

3.3.5 ws_app.py

import json

from geventwebsocket.websocket import WebSocket
from geventwebsocket.server import WSGIServer
from geventwebsocket.handler import WebSocketHandler
from flask import Flask, request

app = Flask(__name__)
app.debug = True

socket_dict = {}


@app.route('/app/<username>')
def app_ws(username):
    sock = request.environ.get('wsgi.websocket', None)  # type:WebSocket

    if not sock:
        return '请使用WS协议连接'
    while True:
        try:
            socket_dict[username] = sock  # 将用户名与sock作映射关系
            print(socket_dict)
            """获取json序列化后的数据"""
            msg = sock.receive()
            msg_dict = json.loads(msg)  # 反序列化数据为字典
            target_user = msg_dict['receiver']  # 取出数据中的目标用户,以获取对应的sock
            recv_sock = socket_dict[target_user]
            if recv_sock:
                print(recv_sock)
                recv_sock.send(msg)
            else:
                print("无客户端。")
        except:
            """解决刷新页面时,之前已创建的websocket会话关闭产生的错误"""
            break
    return 'ok'


if __name__ == '__main__':
    ws_server = WSGIServer(listener=('0.0.0.0', 81), application=app, handler_class=WebSocketHandler)
    ws_server.serve_forever()

标签:function,Flask,mui,html,user,简单,document,data,HTML5
From: https://www.cnblogs.com/f-carey/p/17300641.html

相关文章

  • spring security自动配置的源码简单分析
    本文基于的springboot版本是2.1.3.RELEASE,用springboot来自动配置springsecurity,一、综述在springboot中使用springsecurity只需要引入如下依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId&......
  • 【python】使用build模块进行简单打包分发
    build模块build模块是python3.6引入的一个简单的打包工具,和setuptools的区别是,build更加灵活简单,而setuptools提供了很多的高级功能,可以更加灵活的满足不同的项目需求   也就是说,build提供了一个简单的标准库级别的构建和打包工具,而setuptools更加强大安装buildpython......
  • Flask 学习
    Flask目录Flask1flask简介2Flask2.1Flaskresponse2.2FlaskRequest2.3Flask中的Session2.4Flask模板语言2.4.1Jinja22.5Flask路由2.6Flask初始化实例化参数2.7Flasksetting2.8FlaskBluePrint2.8.1使用Flask模拟Django2.9.2Flask-session模块使用2.9Flask......
  • flask---day04()
    上节回顾#1蓝图 -第一步:导入-第二步:实例化得到对象,可以指定static和templates-第三步:app中注册蓝图,注册蓝图时,可以指定前缀-第四步:使用蓝图,注册路由,注册请求扩展#2g对象 -当次请求的全局对象,在当次请求中可以放值和取值-跟session的区......
  • C语言的回调函数原来这么简单
    手机端阅读:C语言的回调函数原来这么简单 了解开发语言的朋友应该都会对回调函数有所了解,在很多的程序开发语言中都能看到回调的身影。很多场景下,当某个条件成立以后我们希望代码执行某些指定的部分,这个时候可以考虑使用回调函数的方式,这样做思路更加的清晰,也能使代码结构的逻辑更加......
  • 简单分享-项目中监听文件夹及文件的方法
    首先实现对应接口importorg.apache.commons.io.monitor.FileAlterationListenerAdaptor;importjava.io.File;publicclassFilterListenerextendsFileAlterationListenerAdaptor{@OverridepublicvoidonDirectoryCreate(Filedirectory){System.ou......
  • 剑指offer05(Java)-替换空格(简单)
    题目:请实现一个函数,把字符串s中的每个空格替换成"%20"。 示例1:输入:s="Wearehappy."输出:"We%20are%20happy." 限制:0<=s的长度<=10000来源:力扣(LeetCode)链接:https://leetcode.cn/problems/ti-huan-kong-ge-lcof著作权归领扣网络所有。商业转载请联系官方授权,......
  • 将Vue项目部署到Tomcat服务器上(简单、粗暴)
    1.将项目打包Vue中自带webpack,可以通过一行命令将项目打包#执行该命令打包npmrunbuild2.上传相应文件到服务器上打包完成后,项目中会多出一个dist文件夹,这个文件夹中就包含html、css、js等文件直接将dist文件夹上传到Tomcat的ROOT目录下,默认情况下,访问服务器网址......
  • 力扣1076(MySQL)-员工项目Ⅱ(简单)
    题目:编写一个SQL查询,报告所有雇员最多的项目。查询结果格式如下所示:  解题思路:方法一:将两个表联结,以project_id进行分组,统计员工数降序排序,然后筛选出第一条数据。1selectproject_id2fromprojecta3joinemployeeb4ona.employee_id=b.employee_id5group......
  • 力扣1075(MySQL)-项目员工Ⅰ(简单)
    题目:项目表 Project:  员工表 Employee:请写一个SQL 语句,查询每一个项目中员工的 平均 工作年限,精确到小数点后两位。查询结果的格式如下:   解题思路:建表语句:1CreatetableIfNotExistsProject_1075(project_idint,employee_idint);2Createtable......