python 全栈开发,Day126(创业故事,软件部需求,内容采集,显示内容图文列表,MongoDB数据导入导出JSON)

做业讲解

下载代码:javascript

HBuilder APP和flask后端登陆css

连接:https://pan.baidu.com/s/1eBwd1sVXTNLdHwKRM2-ytg 密码:4pcwhtml

如何打开APP和后端flask,请参数昨天的文章前端

 

进入flask后端程序目录,建立文件setting.pyhtml5

设置MongoDB信息,以及json返回格式java

import pymongo

client = pymongo.MongoClient(host="127.0.0.1", port=27017)
MONGO_DB = client["bananabase"]


RET = {
    # 0: false 2: True
    "code": 0,
    "msg": "",  # 提示信息
    "data": {}
}
View Code

 

修改后端的 manager.pygit

from flask import Flask, request,jsonify
from setting import MONGO_DB
from setting import RET

app = Flask(__name__)


@app.route('/')
def hello_world():
    return 'Hello World!'


@app.route('/login',methods=["POST"])
def login():
    username = request.form.get("username")
    password = request.form.get("password")
    if username == "xiao" and password == "123":
        return "欢迎登录"

    return "登录失败"


@app.route('/reg',methods=["POST"])
def reg():
    """
    注册
    :return: {"code":0,"msg":"","data":""}
    """
    try:
        username = request.form.get("username")
        password = request.form.get("password")
        age = request.form.get("age")
        nickname = request.form.get("nickname")
        gender = request.form.get("gender")
        phone = request.form.get("phone")

        user_info = {
            "username": username,
            "password": password,
            "age": age,
            "nickname": nickname,
            "gender": gender,
            "phone": phone
        }

        res = MONGO_DB.users.insert_one(user_info)
        user_id = str(res.inserted_id)

        RET["code"] = 0
        RET["msg"] = "注册成功"
        RET["data"] = user_id
    except Exception as e:
        RET["code"] = 1
        RET["msg"] = "注册失败"

    return jsonify(RET)

if __name__ == '__main__':
    app.run("0.0.0.0", 9527, debug=True)
View Code

此时,项目结构以下:github

./
├── manager.py
├── setting.py
├── static
└── templates

 

全局变量

因为多个html页面,须要引用同一个变量。这个时候,须要定义一个全局变量!如何定义呢?web

默认包含了mui的html文件都导入mui.js文件。那么将变量写在mui.js中,就能够实现全部页面共享了!mongodb

 

因为开发环境的电脑的IP是自动获取的,隔一段时间,就须要修改一次。那么html中发送POST请求时,URL中的IP地址不能写死!

全部 JavaScript 全局对象、函数以及变量均自动成为 window 对象的成员。

修改mui.js,定义全局变量,务必使用windows

 * MUI核心JS
 * @type _L4.$|Function
 */

window.serv = "http://192.168.11.85:9527"

window.styles = {
    top: "0px",
    bottom: "50px"
};

...

因为代码过多,用...省略了!

特别注意:虽然HBuilder,夜神模拟器,Flask后端,所有都在同一台电脑。可是window.serv的IP地址不能是127.0.0.1。

不然点击注册时彻底没有反应,后端也收不到数据!由于它发给模拟器自己了!

 

md5.js

MD5.js是经过前台js加密的方式对密码等私密信息进行加密的工具

 

前端注册页面的密码,发送给后端时,须要用md5加密。防止密码在网络中被黑客截获!须要用到md5.js

 

打开bootcdn网页,搜索md5.js

https://www.bootcdn.cn/blueimp-md5/

下载md5.min.js,放到MyApp目录中的js文件夹中!

 

修改reg.html,导入js,并增长相关js代码,发送POST请求

<!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">用户注册</h1>
        </header>
        <div class="mui-content">
            <form class="mui-input-group" style="margin-top: 15px;">
                <div class="mui-input-row">
                    <label>用户名</label>
                    <input type="text" class="mui-input-clear" placeholder="请输入用户名" id="username">
                </div>
                <div class="mui-input-row">
                    <label>密码</label>
                    <input type="password" class="mui-input-password" placeholder="请输入密码" id="pwd">
                </div>
                <div class="mui-input-row">
                    <label>确认密码</label>
                    <input type="password" class="mui-input-password" placeholder="请输入密码" id="repwd">
                </div>
                <div class="mui-input-row">
                    <label>昵称</label>
                    <input type="text" class="mui-input-clear" placeholder="请输入昵称" id="nickname">
                </div>
                <div class="mui-input-row mui-radio mui-left">
                    <label>男</label>
                    <input name="gender" type="radio" value="1">
                </div>
                <div class="mui-input-row mui-radio mui-left">
                    <label>女</label>
                    <input name="gender" type="radio" value="2" checked>
                </div>
                <div class="mui-input-row">
                    <label>年龄</label>
                    <input type="text" class="mui-input-clear" placeholder="请输入年龄" id="age">
                </div>
                <div class="mui-input-row">
                    <label>电话</label>
                    <input type="text" class="mui-input-clear" placeholder="请输入电话" id="phone">
                </div>
                <div class="mui-button-row">
                    <button type="button" class="mui-btn mui-btn-primary" id="reg">注册</button>
                    <button type="button" class="mui-btn mui-btn-danger mui-action-back">返回</button>
                </div>
            </form>
        </div>
    </body>

    <script src="js/mui.js" type="text/javascript" charset="utf-8"></script>
    <!--加载md5-->
    <script src="js/md5.min.js" type="text/javascript" charset="utf-8"></script>
    <script type="text/javascript">
        mui.init()
        // id为reg的标签绑定点击事件
        document.getElementById("reg").addEventListener("tap",function(){
            
            // 获取全部性别列表
            var gender_list = document.getElementsByName("gender")

            var pwd = document.getElementById("pwd").value;  //密码
            
            if (pwd.length == 0){
                mui.toast("密码不能为空")
                return
            }
            
            var repwd = document.getElementById("repwd").value;  //确认密码
            // 判断2次密码
            if(pwd != repwd) {
                mui.toast("两次密码输入不一致")
                return
            }
            // md5方法为md5.min.js内置方法
            pwd = md5(pwd);  //使用md5方法对密码作md5

            var username = document.getElementById("username").value;  //用户名
            var age = document.getElementById("age").value;  //年龄
            var nickname = document.getElementById("nickname").value;  //昵称
            var phone = document.getElementById("phone").value;  //电话

            var gender = null;  //性别
            // 遍历性别列表
            for(var i = 0; i < gender_list.length; i++) {
                // checked表示选中,当标签被被选中时
                if(gender_list[i].checked) {
                    // 获取选中的性别,i表示索引
                    gender = gender_list[i].value;
                }
            }
            
            // 发送POST请求
            mui.post(
                // window.serv + "/reg"表示 http://192.168.11.85:9527/reg
                window.serv + "/reg", {
                    // 下面是须要发送的键值对
                    username: username,
                    password: pwd,
                    gender: gender,
                    age: age,
                    nickname: nickname,
                    phone: phone
                },
                function(data){
                    // 因为后端返回的是json,这里须要反序列化
                    console.log(JSON.stringify(data))
                    if (!data.code){
                        mui.toast(data.msg)
                    }else{
                        mui.toast(data.msg)
                    }
                }
            )
            
        })
    </script>

</html>
View Code

 

使用模拟器访问

底部会有提示

使用客户端打开MongoDB,查看数据

查看HBuilder控制台输出:

 {"code":0,"data":"5b9bb768e1253281608e96eb","msg":"注册成功"} at reg.html:114

 

因为后端的登陆逻辑, 用户名和密码写死了,须要从MongoDB中获取

修改  manager.py

from flask import Flask, request,jsonify
from setting import MONGO_DB
from setting import RET

app = Flask(__name__)


@app.route('/')
def hello_world():
    return 'Hello World!'


@app.route('/login',methods=["POST"])
def login():
    """
    登录验证
    :return: settings -> RET
    """
    try:
        RET["code"] = 1
        RET["msg"] = "用户名或密码错误"
        RET["data"] = {}

        username = request.form.get("username")
        password = request.form.get("password")

        user = MONGO_DB.users.find_one({"username": username, "password": password})

        if user:
            # 因为user中的_id是ObjectId对象,须要转化为字符串
            user["_id"] = str(user.get("_id"))
            RET["code"] = 0
            RET["msg"] = "欢迎登录"
            RET["data"] = {"user_id": user.get("_id")}

    except Exception as e:
        RET["code"] = 1
        RET["msg"] = "登录失败"

    return jsonify(RET)


@app.route('/reg',methods=["POST"])
def reg():
    """
    注册
    :return: {"code":0,"msg":"","data":""}
    """
    try:
        username = request.form.get("username")
        password = request.form.get("password")
        age = request.form.get("age")
        nickname = request.form.get("nickname")
        gender = request.form.get("gender")
        phone = request.form.get("phone")

        user_info = {
            "username": username,
            "password": password,
            "age": age,
            "nickname": nickname,
            "gender": gender,
            "phone": phone
        }

        res = MONGO_DB.users.insert_one(user_info)
        user_id = str(res.inserted_id)

        RET["code"] = 0
        RET["msg"] = "注册成功"
        RET["data"] = user_id
    except Exception as e:
        RET["code"] = 1
        RET["msg"] = "注册失败"

    return jsonify(RET)

if __name__ == '__main__':
    app.run("0.0.0.0", 9527, debug=True)
View Code

 

修改 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" style="margin-top: 15px;">
                    <label>用户名</label>
                    <input type="text" class="mui-input-clear" placeholder="请输入用户名" id="username">
                </div>
                <div class="mui-input-row">
                    <label>密码</label>
                    <input type="password" class="mui-input-password" placeholder="请输入密码" id="pwd">
                </div>
                <div class="mui-button-row">
                    <button type="button" class="mui-btn mui-btn-red" id="login">登录</button>
                    <button type="button" class="mui-btn mui-btn-green" id="reg">注册</button>
                </div>
            </form>
        </div>
    </body>

    <script src="js/mui.js" type="text/javascript" charset="utf-8"></script>
    <!--加载md5-->
    <script src="js/md5.min.js" type="text/javascript" charset="utf-8"></script>
    <script type="text/javascript">
        mui.init()
        document.getElementById("login").addEventListener("tap", function() {
            var uname = document.getElementById("username").value;
            var pwd = document.getElementById("pwd").value;
            pwd = md5(pwd);
            
            mui.post(
                window.serv + "/login", {
                    username: uname,
                    password: pwd
                },
                function(data) {
                    // 因为后端返回的是json,这里须要反序列化
                    console.log(JSON.stringify(data))
                    if (!data.code){
                        mui.toast(data.msg)
                    }else{
                        mui.toast(data.msg)
                    }
                }
            );
        });

        document.getElementById("reg").addEventListener("tap", function() {
            mui.openWindow({
                url: "reg.html",
                id: "reg.html"
            })
        })
    </script>

</html>
View Code

因为MongoDB中的用户表的密码字段,使用了md5加密。因此这里发送给后端的密码,也须要md5加密

 

从新登陆,输入正确的用户名和密码

底部提示

 

 

做业要求,登陆成功后,将用户ID返回给前端,而且由index页面打印欢迎{用户ID}登录

这个时候,须要使用开火(fire)事件

 

修改 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" style="margin-top: 15px;">
                    <label>用户名</label>
                    <input type="text" class="mui-input-clear" placeholder="请输入用户名" id="username">
                </div>
                <div class="mui-input-row">
                    <label>密码</label>
                    <input type="password" class="mui-input-password" placeholder="请输入密码" id="pwd">
                </div>
                <div class="mui-button-row">
                    <button type="button" class="mui-btn mui-btn-red" id="login">登录</button>
                    <button type="button" class="mui-btn mui-btn-green" id="reg">注册</button>
                </div>
            </form>
        </div>
    </body>

    <script src="js/mui.js" type="text/javascript" charset="utf-8"></script>
    <!--加载md5-->
    <script src="js/md5.min.js" type="text/javascript" charset="utf-8"></script>
    <script type="text/javascript">
        mui.init()
        document.getElementById("login").addEventListener("tap", function() {
            var uname = document.getElementById("username").value;
            var pwd = document.getElementById("pwd").value;
            pwd = md5(pwd);
            
            mui.post(
                window.serv + "/login", {
                    username: uname,
                    password: pwd
                },
                function(data) {
                    // 因为后端返回的是json,这里须要反序列化
                    console.log(JSON.stringify(data))
                    if (!data.code){
                        // mui.toast(data.msg)
                        // index页面的WebviewById为HBuilder
                        var index = plus.webview.getWebviewById("HBuilder")
                        // 触发fire事件,发送数据
                        mui.fire(index,"login",{msg:data.msg + data.data.user_id})
                    }else{
                        mui.toast(data.msg)
                    }
                }
            );
        });

        document.getElementById("reg").addEventListener("tap", function() {
            mui.openWindow({
                url: "reg.html",
                id: "reg.html"
            })
        })
    </script>

</html>
View Code

 

修改 index.html

<!DOCTYPE html>
<html>

    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <title></title>
        <script src="js/mui.js"></script>
        <link href="css/mui.min.css" rel="stylesheet" />
    </head>

    <body>
        <nav class="mui-bar mui-bar-tab">
            <a class="mui-tab-item mui-active" id="index">
                <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">
                <span class="mui-icon mui-icon-email"></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>
    </body>
    <script type="text/javascript" charset="utf-8">
        mui.init({
            subpages: [{
                url: "main.html",
                id: "main.html",
                styles: window.styles
            }]
        });
        mui.plusReady(function() {
            console.log(JSON.stringify(plus.webview.currentWebview()))
        });

        document.getElementById("phone").addEventListener("tap", function() {
            mui.toast("你點擊了電話按鈕");

            mui.openWindow({
                url: "phone.html",
                id: "phone.html",
                styles: window.styles,
                extras: {
                    user_id: 123456
                }
            })
        })

        document.getElementById("index").addEventListener("tap", function() {
            mui.openWindow({
                url: "main.html",
                id: "main.html",
                styles: window.styles
            })
        })

        document.getElementById("login").addEventListener("tap", function() {
            mui.openWindow({
                url: "login.html",
                id: "login.html",
                styles: window.styles
            })
        })
        
        document.addEventListener("login",function(data){
            // fire事件接收消息,使用data.detail
            // index是为作显示区分
            mui.toast("index"+data.detail.msg)
        })
    </script>

</html>
View Code

 

从新登陆,底部提示,效果以下:

 

做业需求基本上,就完成了!

可是用户登陆以后,应该跳转到用户主页才对!

 

Storage

Storage模块管理应用本地数据存储区,用于应用数据的保存和读取。应用本地数据与localStorage、sessionStorage的区别在于数据有效域不一样,前者可在应用内跨域操做,数据存储期是持久化的,而且没有容量限制。经过plus.storage可获取应用本地数据管理对象。

方法:

  • getLength: 获取应用存储区中保存的键值对的个数
  • getItem: 经过键(key)检索获取应用存储的值
  • setItem: 修改或添加键值(key-value)对数据到应用数据存储中
  • removeItem: 经过key值删除键值对存储的数据
  • clear: 清除应用全部的键值对存储数据
  • key: 获取键值对中指定索引值的key值

 

参考连接:

http://www.html5plus.org/doc/zh_cn/storage.html

 

新建一个 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">用户信息</h1>
        </header>
        <div class="mui-content">
            <ul class="mui-table-view">
                <li class="mui-table-view-cell"><span>用户名</span><span id="username" class="mui-pull-right">111</span></li>
                <li class="mui-table-view-cell"><span>昵称</span><span id="nickname" class="mui-pull-right">22</span></li>
            </ul>

            <button type="button" class="mui-btn mui-btn-blue mui-btn-block" id="logout">退出登录</button>
        </div>

    </body>
    <script src="js/mui.js" type="text/javascript" charset="utf-8"></script>
    <script type="text/javascript">
        mui.init()
        mui.back = function() {};
        mui.plusReady(function() {
            // 当前web视图
            var Sdata = plus.webview.currentWebview();
            mui.post(
                window.serv + "/user_info", {
                    // Sdata.user_id,这里面的user_id是由login.html传递过来的
                    user_id: Sdata.user_id
                },
                function(data) {
                    console.log(JSON.stringify(data));
                    // 修改页面的text属性
                    document.getElementById("username").innerText = data.username;
                    document.getElementById("nickname").innerText = data.nickname;
                }
            )
        })

        document.getElementById("logout").addEventListener("tap", function() {
            // 删除storage里面的user属性
            plus.storage.removeItem("user")
            // 跳转页面login.html
            mui.openWindow({
                url: "login.html",
                id: "login.html",
                styles: window.styles
            })
        })
    </script>

</html>
View Code

 

修改login.html,给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">登录</h1>
        </header>
        <div class="mui-content">
            <form class="mui-input-group">
                <div class="mui-input-row" style="margin-top: 15px;">
                    <label>用户名</label>
                    <input type="text" class="mui-input-clear" placeholder="请输入用户名" id="username">
                </div>
                <div class="mui-input-row">
                    <label>密码</label>
                    <input type="password" class="mui-input-password" placeholder="请输入密码" id="pwd">
                </div>
                <div class="mui-button-row">
                    <button type="button" class="mui-btn mui-btn-red" id="login">登录</button>
                    <button type="button" class="mui-btn mui-btn-green" id="reg">注册</button>
                </div>
            </form>
        </div>
    </body>

    <script src="js/mui.js" type="text/javascript" charset="utf-8"></script>
    <!--加载md5-->
    <script src="js/md5.min.js" type="text/javascript" charset="utf-8"></script>
    <script type="text/javascript">
        mui.init()
        document.getElementById("login").addEventListener("tap", function() {
            var uname = document.getElementById("username").value;
            var pwd = document.getElementById("pwd").value;
            pwd = md5(pwd);
            
            mui.post(
                window.serv + "/login", {
                    username: uname,
                    password: pwd
                },
                function(data) {
                    // 因为后端返回的是json,这里须要反序列化
                    console.log(JSON.stringify(data))
                    if (!data.code){
                        // mui.toast(data.msg)
                        // index页面的WebviewById为HBuilder
                        //var index = plus.webview.getWebviewById("HBuilder")
                        // 触发fire事件,发送数据
                        //mui.fire(index,"login",{msg:data.msg + data.data.user_id})
                        mui.toast(data.msg + data.data.user_id);
                        //window.location.Storage.setItem("user",data.data.user_id);
                        //修改或添加键值(key-value)对数据到应用数据存储中
                        plus.storage.setItem("user", data.data.user_id);
                        mui.openWindow({
                            url:"user_info.html",
                            id:"user_info.html",
                            styles:window.styles,
                            //使用 extras实现页面间传值
                            extras:{
                                // 传输user_id
                                user_id:data.data.user_id
                            }
                        });
                    }else{
                        mui.toast(data.msg)
                    }
                }
            );
        });

        document.getElementById("reg").addEventListener("tap", function() {
            mui.openWindow({
                url: "reg.html",
                id: "reg.html"
            })
        })
    </script>

</html>
View Code

 

修改后端 manager.py,增长uesr_info

from flask import Flask, request,jsonify
from setting import MONGO_DB
from setting import RET
from bson import ObjectId

app = Flask(__name__)


@app.route('/')
def hello_world():
    return 'Hello World!'


@app.route('/login',methods=["POST"])
def login():
    """
    登录验证
    :return: settings -> RET
    """
    try:
        RET["code"] = 1
        RET["msg"] = "用户名或密码错误"
        RET["data"] = {}

        username = request.form.get("username")
        password = request.form.get("password")

        user = MONGO_DB.users.find_one({"username": username, "password": password})

        if user:
            # 因为user中的_id是ObjectId对象,须要转化为字符串
            user["_id"] = str(user.get("_id"))
            RET["code"] = 0
            RET["msg"] = "欢迎登录"
            RET["data"] = {"user_id": user.get("_id")}

    except Exception as e:
        RET["code"] = 1
        RET["msg"] = "登录失败"

    return jsonify(RET)


@app.route('/reg',methods=["POST"])
def reg():
    """
    注册
    :return: {"code":0,"msg":"","data":""}
    """
    try:
        username = request.form.get("username")
        password = request.form.get("password")
        age = request.form.get("age")
        nickname = request.form.get("nickname")
        gender = request.form.get("gender")
        phone = request.form.get("phone")

        user_info = {
            "username": username,
            "password": password,
            "age": age,
            "nickname": nickname,
            "gender": gender,
            "phone": phone
        }

        res = MONGO_DB.users.insert_one(user_info)
        user_id = str(res.inserted_id)

        RET["code"] = 0
        RET["msg"] = "注册成功"
        RET["data"] = user_id
    except Exception as e:
        RET["code"] = 1
        RET["msg"] = "注册失败"

    return jsonify(RET)


@app.route('/user_info', methods=["POST"])
def user_info():
    user_id = request.form.get("user_id")

    # "password": 0 表示忽略密码字段
    res = MONGO_DB.users.find_one({"_id": ObjectId(user_id)}, {"password": 0})
    if res:
        res["_id"] = str(res.get("_id"))

    RET["code"] = 0
    RET["msg"] = ""
    RET["data"] = res

    return jsonify(res)

if __name__ == '__main__':
    app.run("0.0.0.0", 9527, debug=True)
View Code

 

使用模拟器从新登陆,会自动跳转用户页面,效果以下:

底部有提示

 

总结:

mui的全局变量:
    配置文件,使用windows

    页面视图中,使用storage:
    plus.storage.setItem("key",value) # 设置storage全局变量
    plus.storage.getItem("key") # 获取全局的storage 获取到了就是 value 获取不到就是 Null 
    plus.storage.removeItem("key") # 清除storage

 

1、创业故事

背景人物

老张

老张,它是一个拥有十几年工做经验的销售,40岁左右。 籍贯是黑龙江哈尔滨,长子5岁,小女3岁。 在北京闯荡多年,长期与妻小分离。不想让孩子用手机沟通,由于有辐射。

忽然想孩子了,怎么办呢?思考了一问题,留守儿童如何父母建议有效的沟通。对于孩子而言,玩具是陪伴时间最长的。如何让让玩具成为孩子伙伴帮助孩子成长,让玩具成为与父母沟通的桥梁?

那么玩具须要能发送语音消息,玩具还能够和周围的小伙伴沟通。造成一个良好的社交圈!

这个时候,打了一个电话给老李

老李

老李,作了几十年的产品,懂一点技术,37岁。籍贯是陕西西安,女儿4岁。在在北京闯荡多年,也是留守了本身的女儿在外地。 接到老张的电话以后,立马想到须要技术实现。

这个时候,想到了一个技术比较不错的闫帅。

闫帅

闫帅,29岁,作了8年的技术 ,曾经与老李是同事,接到老李电话,一拍即合。

故事剧情

老张从打电话到公司组建,花了3天的时间
老李,负责设计产品。
闫帅介入,想到涉及到硬件了。对于硬件不精通,须要请硬件老师。招兵买马,组件了技术团队!

公司成立

1.行政人力财务综合部 1我的
2.产品部:老李 + UI 小姐姐 2我的
3.软件部:闫帅 + 1前端 + 后端 3我的
4.硬件部:江老师 + 硬件工程师(1人)
5.营销部:老张 + 1 个运营

2、软件部需求

项目的需求明确

 

1.留守儿童,让玩具成为孩子伙伴帮助孩子成长,让玩具成为与父母沟通的桥梁(语音消息)
2.能让玩具成为一个朋友圈的沟通工具(社交圈)

细化需求

1.玩具:硬件方案--(皮毛(真皮)175,硬件135 ,人工硬件组装15,皮毛人工60,运费:12,包装35)订价:499,初期销售了20个!
2.让玩具成为孩子伙伴
3.帮助孩子成长
4.让玩具成为与父母沟通的桥梁(语音消息)
5.若是能让玩具成为一个朋友圈的沟通工具(社交圈)

如何开发

闫帅与老李沟通商讨如何开发,闫帅开始部署后端
1. 1个前端 + 闫帅 + 1个全栈工程师(先作后端在作前端)
2. 由于闫帅的疏忽严厉批评一次前端,前端离职了,全栈工程师包揽了前端的活
3. 全栈工程师通过8个月以后,成为了公司的产品的大拿

人工智能

为啥不作ai底层开发?150万上下,不足以支撑底层开发!
使用第三方:百度ai,体验不行!花钱买了科大讯飞的服务

 

3、内容采集

分析数据

主要是针对儿童的,须要采集一些儿歌。这里使用 喜马拉雅FM,官方地址:

https://www.ximalaya.com/

 

点击儿童分类,这里主要采集  一千零一晚上频道 ,由于声音比较好听。具备优秀的配音员团队。

https://www.ximalaya.com/zhubo/9216785/

 

选择 一千零一晚上经典儿歌 专辑

https://www.ximalaya.com/ertong/424529/

 

先来访问 新年偏偏 的连接,在新窗口中打开

https://www.ximalaya.com/ertong/424529/7713678

 

点击分享

点击 展开获取声音连接

点击 微电台的连接

连接以下:

http://m.ximalaya.com/sound/7713678

 

打开浏览器工具,点击network

点击上面的播放按钮,它会发送网络请求,点击7713678.json

查看Preview,它是一个json数据,这个就是咱们须要的。

 

 

往下拉,找到play_path,复制地址,网页直接访问!

这里的文件名,进行了加密。单这不重要,只要能访问就行!

http://audio.xmcdn.com/group12/M00/3B/B2/wKgDXFWcw12y8TanAAtkIsI9320251.m4a

网页就直接播放了

经过这一段json,咱们须要5个信息

播放地址(play_path),图片地址(cover_url),简介(intro),昵称(nickname),标题(title)

 

查看Headers,它的请求地址是

http://m.ximalaya.com/tracks/7713678.json

和前面的7713678.json是同样的

和专辑页面的id也是同样的

 

那么经过这个id,拼接路径,就能够访问其余歌曲了,规律是:

http://m.ximalaya.com/tracks/歌曲id.json

 

采集数据

这里使用的是requests模块。请确保安装了

pip install requests

 

新建一个文件 xiaopapa.py

import requests

XMLY_URL = "http://m.ximalaya.com/tracks/"

# 从专辑列表获取的a标签的herf属性
content_url = "/ertong/424529/7713678"

# rsplit从右向左寻找,以某个元素为中心将左右分割成两个元素并放入列表中
# rsplit("/",1) 这里面的1表示分割次数,只分割一次
# [-1] 取最后一个元素
pid = content_url.rsplit("/",1)[-1]  # 获取歌曲id,也就是7713678

# 拼接url,也就是http://m.ximalaya.com/tracks/7713678.json
xiaopapa_url = XMLY_URL + pid + ".json"


content = requests.get(xiaopapa_url)  # get方式访问url
# 获取返回结果,使用content.content。因为是bytes类型,须要解码
print(content.content.decode("utf-8"))
View Code

执行输出,因为内容过长,这里省略了一部分

{"id":7713678,"play_path_64":"...","play_path_32":"...","play_path":"http://audio.xmcdn.com/group12/M00/3B/B2/wKgDXFWcw12y8TanAAtkIsI9320251.m4a","duration":92,"title":"新年偏偏","nickname":"一千零一晚上频"...}

注意:此连接,不要频繁范围,不然会封锁IP的!

 

f-string

它是一种改进Python格式字符串的新方法。

好消息是,F字符串在这里能够节省不少的时间。他们确实使格式化更容易。他们自Python 3.6开始加入标准库。您能够在PEP 498中阅读全部内容。

也称为“格式化字符串文字”,F字符串是开头有一个f的字符串文字,以及包含表达式的大括号将被其值替换。表达式在运行时进行渲染,而后使用__format__协议进行格式化。与往常同样,Python文档是您想要了解更多信息的最佳读物。

如下是f-strings可让你的生活更轻松的一些方法。

简单例子

语法与str.format()使用的语法相似,可是在一些细节部分,比较啰嗦。看看这是多么容易可读:

name = "Eric"
age = 74
res = f"Hello, {name}. You are {age}."
print(res)

执行输出:

Hello, Eric. You are 74.

 

使用大写字母F也是有效的:

res = F"Hello, {name}. You are {age}."

执行输出,效果同上!

 

若是你正好使用了Python 3.6,丢弃format(),用f()吧!

 

上面的xiaopapa.py,输出的是一个json数据,须要反序列化,获取须要的5个信息

import requests
import json

XMLY_URL = "http://m.ximalaya.com/tracks/"

# 从专辑列表获取的a标签的herf属性
content_url = "/ertong/424529/7713678"

# rsplit从右向左寻找,以某个元素为中心将左右分割成两个元素并放入列表中
# rsplit("/",1) 这里面的1表示分割次数,只分割一次
# [-1] 取最后一个元素
pid = content_url.rsplit("/",1)[-1]  # 获取歌曲id,也就是7713678

# 拼接url,也就是http://m.ximalaya.com/tracks/7713678.json
xiaopapa_url = XMLY_URL + pid + ".json"


content = requests.get(xiaopapa_url)  # get方式访问url
# 获取返回结果,使用content.content。因为是bytes类型,须要解码
content_dict = json.loads(content.content.decode("utf8"))

play_path = content_dict.get("play_path")  # 播放地址
cover_url = content_dict.get("cover_url")  # 图片地址

intro = content_dict.get("intro")  # 简介
nickname = content_dict.get("nickname")  # 昵称
title = content_dict.get("title")  # 标题

print(play_path)
print(cover_url)
print(intro)
print(nickname)
print(title)
View Code

执行输出:

http://audio.xmcdn.com/group12/M00/3B/B2/wKgDXFWcw12y8TanAAtkIsI9320251.m4a
http://fdfs.xmcdn.com/group9/M04/3B/E1/wKgDZlWcvRKwSOIMAAD3201gPxc590.jpg
【一千零一晚上】经典儿歌
一千零一晚上频道
新年偏偏

 

有了这些信息,就能够下载音频和图片了

新建目录audio和audio_img

此时目录结构以下:

./
├── audio
├── audio_img
├── manager.py
├── setting.py
├── static
├── templates
└── xiaopapa.py

 

写入文件

为了统一管理,将喜马拉雅FM的url和文件目录写入配置文件

修改setting.py

import pymongo

client = pymongo.MongoClient(host="127.0.0.1", port=27017)
MONGO_DB = client["bananabase"]


RET = {
    # 0: false 2: True
    "code": 0,
    "msg": "",  # 提示信息
    "data": {}
}

XMLY_URL = "http://m.ximalaya.com/tracks/"  # 喜马拉雅连接

# 文件目录
import os

AUDIO_FILE = os.path.join(os.path.dirname(__file__), "audio")
AUDIO_IMG_FILE = os.path.join(os.path.dirname(__file__), "audio_img")
View Code

 

修改manager.py,文件名使用uuid4,防止重名

import requests
import json
import os
import setting
from uuid import uuid4

XMLY_URL = "http://m.ximalaya.com/tracks/"

# 从专辑列表获取的a标签的herf属性
content_url = "/ertong/424529/7713678"
category = "erge"  # 分类

# rsplit从右向左寻找,以某个元素为中心将左右分割成两个元素并放入列表中
# rsplit("/",1) 这里面的1表示分割次数,只分割一次
# [-1] 取最后一个元素
pid = content_url.rsplit("/",1)[-1]  # 获取歌曲id,也就是7713678

# 拼接url,也就是http://m.ximalaya.com/tracks/7713678.json
xiaopapa_url = XMLY_URL + pid + ".json"


content = requests.get(xiaopapa_url)  # get方式访问url
# 获取返回结果,使用content.content。因为是bytes类型,须要解码
content_dict = json.loads(content.content.decode("utf8"))

play_path = content_dict.get("play_path")  # 播放地址
cover_url = content_dict.get("cover_url")  # 图片地址

intro = content_dict.get("intro")  # 简介
nickname = content_dict.get("nickname")  # 昵称
title = content_dict.get("title")  # 标题

file_name = f"{uuid4()}"  # 随机文件名
audio = f"{file_name}.mp3"  # 音频
image = f"{file_name}.jpg"  # 图片

audio_file = requests.get(play_path).content  # 访问音频连接,获取二进制数据
with open(os.path.join(setting.AUDIO_FILE, audio), "wb") as f:
    f.write(audio_file)  # 写入文件

image_file = requests.get(cover_url).content  # 访问图片连接,获取二进制数据
with open(os.path.join(setting.AUDIO_IMG_FILE, image), "wb") as f:
    f.write(image_file)  # 写入文件
View Code

执行 manager.py,此时audio和audio_img分别多出一个文件

80c5fe21-de1a-4b59-a9c6-cbeb1c2691be.mp3

80c5fe21-de1a-4b59-a9c6-cbeb1c2691be.jpg

 

写入 MongoDB 数据库

谁知道,这2个文件,对应是 新年偏偏 呢?须要写入数据库,这里采用MongoDB

修改 manager.py

import requests
import json
import os
import setting
from uuid import uuid4

XMLY_URL = "http://m.ximalaya.com/tracks/"

# 从专辑列表获取的a标签的herf属性
content_url = "/ertong/424529/7713678"
category = "erge"  # 分类

# rsplit从右向左寻找,以某个元素为中心将左右分割成两个元素并放入列表中
# rsplit("/",1) 这里面的1表示分割次数,只分割一次
# [-1] 取最后一个元素
pid = content_url.rsplit("/",1)[-1]  # 获取歌曲id,也就是7713678

# 拼接url,也就是http://m.ximalaya.com/tracks/7713678.json
xiaopapa_url = XMLY_URL + pid + ".json"


content = requests.get(xiaopapa_url)  # get方式访问url
# 获取返回结果,使用content.content。因为是bytes类型,须要解码
content_dict = json.loads(content.content.decode("utf8"))

play_path = content_dict.get("play_path")  # 播放地址
cover_url = content_dict.get("cover_url")  # 图片地址

intro = content_dict.get("intro")  # 简介
nickname = content_dict.get("nickname")  # 昵称
title = content_dict.get("title")  # 标题

file_name = f"{uuid4()}"  # 随机文件名
audio = f"{file_name}.mp3"  # 音频
image = f"{file_name}.jpg"  # 图片

audio_file = requests.get(play_path).content  # 访问音频连接,获取二进制数据
with open(os.path.join(setting.AUDIO_FILE, audio), "wb") as f:
    f.write(audio_file)  # 写入文件

image_file = requests.get(cover_url).content  # 访问图片连接,获取二进制数据
with open(os.path.join(setting.AUDIO_IMG_FILE, image), "wb") as f:
    f.write(image_file)  # 写入文件

content_db = {
    "title": title,
    "nickname": nickname,
    "avatar": image,
    "audio": audio,
    "intro": intro,
    "category":category,  # 分类
    "play_count": 0  # 播放次数
}

setting.MONGO_DB.sources.insert_one(content_db)  # 插入一条数据
View Code

 

执行 manager.py,使用mongodb客户端,查看数据。发现有一条数据,效果以下:

 

再录入几条数据,打开网页:

https://www.ximalaya.com/ertong/424529/

复制几首歌的id,好比这样

<a title="鱼儿水中游" href="/ertong/424529/7713768">鱼儿水中游</a>
<a title="祝你圣诞快乐" href="/ertong/424529/7713763">祝你圣诞快乐</a>
<a title="祖国祖国咱们爱你" href="/ertong/424529/7713762">祖国祖国咱们爱你</a>
<a title="最美的图画" href="/ertong/424529/7713760">最美的图画</a>

 

修改  manager.py,修改最后的id,由于424529(专辑)是同样的

content_url = "/ertong/424529/7713678"

改为

content_url = "/ertong/424529/7713768"

它表示 鱼儿水中游这首歌曲,运行一次。

其余歌曲,依次类推。最后MongoDB中有5首歌曲

 

5、显示内容图文列表

后端接口

既然数据库有数据了,那么就须要展现到图文列表了。要替换这部份内容

进入flask后端目录,新建目录serv,在此目录下建立文件get_file.py,用来获取音频和图片

from flask import Blueprint, send_file
from setting import AUDIO_FILE
from setting import AUDIO_IMG_FILE
import os

getfile = Blueprint("getfile", __name__)

@getfile.route("/get_audio/<filename>")
def get_audio(filename):  # 获取音频
    sendfile = os.path.join(AUDIO_FILE, filename)
    return send_file(sendfile)

@getfile.route("/get_image/<filename>")
def get_image(filename):  # 获取图片
    sendfile = os.path.join(AUDIO_IMG_FILE, filename)
    return send_file(sendfile)
View Code

 

继续新建content.py

from flask import Blueprint, jsonify
from setting import MONGO_DB
from setting import RET

cont = Blueprint("cont", __name__)


@cont.route("/content_list", methods=["POST"])
def content_list():  # 内容列表
    res_list = list(MONGO_DB.sources.find({}))  # 字典转换列表

    for index, item in enumerate(res_list):  #返回 enumerate(枚举)对象
        # 因为_id是ObjectId对象,转换为字符串
        res_list[index]["_id"] = str(item.get("_id"))

    RET["code"] = 0
    RET["msg"] = ""
    RET["data"] = res_list

    return jsonify(RET)  # 返回json数据
View Code

 

修改 manager.py,注册2个蓝图

from flask import Flask, request,jsonify
from setting import MONGO_DB
from setting import RET
from bson import ObjectId
from serv import get_file
from serv import content

app = Flask(__name__)

app.register_blueprint(get_file.getfile)
app.register_blueprint(content.cont)

@app.route('/')
def hello_world():
    return 'Hello World!'


@app.route('/login',methods=["POST"])
def login():
    """
    登录验证
    :return: settings -> RET
    """
    try:
        RET["code"] = 1
        RET["msg"] = "用户名或密码错误"
        RET["data"] = {}

        username = request.form.get("username")
        password = request.form.get("password")

        user = MONGO_DB.users.find_one({"username": username, "password": password})

        if user:
            # 因为user中的_id是ObjectId对象,须要转化为字符串
            user["_id"] = str(user.get("_id"))
            RET["code"] = 0
            RET["msg"] = "欢迎登录"
            RET["data"] = {"user_id": user.get("_id")}

    except Exception as e:
        RET["code"] = 1
        RET["msg"] = "登录失败"

    return jsonify(RET)


@app.route('/reg',methods=["POST"])
def reg():
    """
    注册
    :return: {"code":0,"msg":"","data":""}
    """
    try:
        username = request.form.get("username")
        password = request.form.get("password")
        age = request.form.get("age")
        nickname = request.form.get("nickname")
        gender = request.form.get("gender")
        phone = request.form.get("phone")

        user_info = {
            "username": username,
            "password": password,
            "age": age,
            "nickname": nickname,
            "gender": gender,
            "phone": phone
        }

        res = MONGO_DB.users.insert_one(user_info)
        user_id = str(res.inserted_id)

        RET["code"] = 0
        RET["msg"] = "注册成功"
        RET["data"] = user_id
    except Exception as e:
        RET["code"] = 1
        RET["msg"] = "注册失败"

    return jsonify(RET)


@app.route('/user_info', methods=["POST"])
def user_info():
    user_id = request.form.get("user_id")

    # "password": 0 表示忽略密码字段
    res = MONGO_DB.users.find_one({"_id": ObjectId(user_id)}, {"password": 0})
    if res:
        res["_id"] = str(res.get("_id"))

    RET["code"] = 0
    RET["msg"] = ""
    RET["data"] = res

    return jsonify(res)

if __name__ == '__main__':
    app.run("0.0.0.0", 9527, debug=True)
View Code

此时目录结构以下:

./
├── audio
├── audio_img
├── manager.py
├── serv
│   ├── content.py
│   └── get_file.py
├── setting.py
├── static
├── templates
└── xiaopapa.py

 

重启 manager.py,访问页面:

http://127.0.0.1:9527/get_image/4ed490e8-aded-4f23-8a7c-c845e48ec778.jpg

注意:后面的图片地址,从MongoDB中复制一条便可!

效果以下:

 

 使用postman访问content_list

 

前端展现

修改js目录下的mui.js,增长全局变量serv_imge

window.serv = "http://192.168.11.86:9527"
window.serv_imge = window.serv+"/get_image/";

window.styles = {
    top: "0px",
    bottom: "50px"
};
...

 

修改mian.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-scroll-wrapper">
            <div class="mui-scroll">
                <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="https://timgsa.baidu.com/timg?image&amp;quality=80&amp;size=b9999_10000&amp;sec=1537023056923&amp;di=e50b27f1a9d34e586e421b50ff5cc0b0&amp;imgtype=0&amp;src=http%3A%2F%2Fatt.bbs.duowan.com%2Fforum%2F201508%2F18%2F173910p7045xys71x4zfyh.jpg"
                                        width="300px" height="400px">
                                </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="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 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" id="content_list">

                    </ul>
                </div>
            </div>

        </div>
    </body>

    <script src="js/mui.js" type="text/javascript" charset="utf-8"></script>
    <script type="text/javascript">
        mui.init()
        mui('.mui-scroll-wrapper').scroll()
        mui.back = function() {
            mui.toast("不让你点")
        };
        
        mui.plusReady(function(){
            // 发送post请求
            mui.post(
                window.serv+"/content_list",  //访问内容列表
                {},  //参数为空
                function(data){
                    console.log(JSON.stringify(data));
                    // for循环列表
                    for (var i = 0; i < data.data.length; i++) {
                        create_content(data.data[i])  // 执行自定义方法create_content
                    }
                }
            )
            
        })
        
        document.addEventListener("talk",function(data){
            mui.toast(data.detail.talk);
        })
        
        function create_content(content){    // 建立内容标签    
            var litag = document.createElement("li");  // 建立li标签
            litag.className = "mui-table-view-cell mui-media";  //添加class
            var atag = document.createElement("a");  // 建立a标签
            atag.id = content._id;  // 设置id
            
            
            var imgtag = document.createElement("img");
            imgtag.className = "mui-media-object mui-pull-left";
            
            imgtag.src = window.serv_imge + content.avatar;  //拼接图片路径
            //console.log(window.serv_imge + content.avatar);
            
            var divtag = document.createElement("div");
            divtag.className = "mui-media-body";
            divtag.innerText = content.title;
            var ptag = document.createElement("p");
            ptag.className = "mui-ellipsis";
            ptag.innerText = content.intro;
             
             litag.appendChild(atag);  //追加到li标签中
             atag.appendChild(imgtag);
             atag.appendChild(divtag);
             divtag.appendChild(ptag);
             
             document.getElementById("content_list").appendChild(litag);  //将li标签添加到ul中
        
        }
        
    </script>

</html>
View Code

 

使用模拟器访问,效果以下:

 

总结:

mui的全局变量:
    plus.storage.setItem("key",value) # 设置storage全局变量
    plus.storage.getItem("key") # 获取全局的storage 获取到了就是 value 获取不到就是 Null 
    plus.storage.removeItem("key") # 清除storage
    
    
2018年9月14日
故事(创业故事)北京xxxxxx科技有限公司:
    背景人物:
        1.老张:40+ 籍贯是黑龙江哈尔滨 长子5 小女3 在北京闯荡 长期与妻小分离 不想让孩子用手机 忽然想孩子了
            思考了一问题:留守儿童,玩具,让玩具成为孩子伙伴帮助孩子成长,让玩具成为与父母沟通的桥梁(语音消息)
            若是能让玩具成为一个朋友圈的沟通工具(社交圈) 销售
        
        2.老李:37 懂一点技术的产品 陕西西安 1女4岁 在北京闯荡 也是留守了本身的女儿 接到老张的电话 须要技术实现
        
        3.闫帅:29 技术 作了8年 与老李是同事,一拍即合 接到老李电话
        
    故事剧情:
        老张从打电话到公司组建,3天
        老李,设计产品
        闫帅介入,涉及到硬件,须要请硬件老师,技术团队
        
        公司成立了:
        1.行政人力财务综合部 1我的
        2.产品部:老李 + UI 小姐姐 2我的
        3.软件部:闫帅 + 1前端 + 后端 3我的
        4.硬件部:江老师 + 硬件工程师(0人) 1我的
        5.营销部:老张 + 1 运营 
        
        项目的需求明确:
            留守儿童,玩具,让玩具成为孩子伙伴帮助孩子成长,让玩具成为与父母沟通的桥梁(语音消息)
            若是能让玩具成为一个朋友圈的沟通工具(社交圈)
            
            1.玩具:硬件方案-------(皮毛175,硬件135 ,人工硬件组装15,皮毛人工60,运费:12,包装35)499 20 
            
            2.让玩具成为孩子伙伴
            3.帮助孩子成长
            4.让玩具成为与父母沟通的桥梁(语音消息)
            5.若是能让玩具成为一个朋友圈的沟通工具(社交圈)
            
        
        闫帅与老李沟通商讨如何开发,闫帅开始部署后端
            1. 1前端 + 闫帅 + 你 先作后端在作前端 全栈工程师
            2. 由于闫帅的疏忽严厉批评一次前端,前端离职了,你吹牛逼说前端两周能够学完成 
            3. 你 成为了公司的产品的大拿 4个月 8个月
        
        
        人工智能:
            150万上下,不足以支撑底层开发的
            第三方:百度ai,太烂了,花钱买了科大讯飞的服务
        
            
    倒闭:
        硬件方案(成本太高)
        管理问题
        资金链,不足以支撑更换硬件方案了
        
        
展开软件部需求:
    2.让玩具成为孩子伙伴 (聊天沟通,内容点播)
    3.帮助孩子成长 (智能百科)
    4.让玩具成为与父母沟通的桥梁(语音消息,websocket ,IM通信,天然语言处理)
    5.若是能让玩具成为一个朋友圈的沟通工具(社交圈)(C端与C端的交流)
    6.app:能与玩具对话 + 内容 + 遥控 + 控制玩具的通信录
    
    孩子说话         --- 百度语音识别 + 天然语言处理
    孩子说话点歌     --- 天然语言处理 + 内容采集 + 内容名称理解
    聊天沟通         --- 图灵
    智能百科         --- 图灵
    语音消息        --- websocket(语音通信)+ IM通信
    c端交流            --- 玩具主动发起消息 ,天然语言处理
    
开发者日志:(开发者笔记)    
1.基于百度ai 和 tuling123 智能对话
2.基于websocket实现了智能语音对话

2018年9月14日:
项目第一天:        
1.内容采集:
    采坑:XMLY采集内容层层加密 分享按钮获得了一个M端的地址,从这个地址中得到到了 
        "http://m.ximalaya.com/tracks/id.json" 获取音频的全部参数
    基于 request / MongoDB    实现数据采集和存储
    
    
2.App显示内容图文列表:
    定义了两个接口 get_image content_list
    接口/get_image 获取图片
    接口/content_list 获取内容列表
    
    app: create_content(content) 用来建立 图文列表元素的
        坑: 点击事件还未完成
    
    
3.注册 登录 自动登录 退出
    

项目名称:智能玩具
项目阐述:需求+完成结果 
项目技术:
    1.基于baidu-aip 和 tuling123 智能对话
    2.基于websocket实现了智能语音对话
    3.基于requests实现内容采集
View Code

 

完整代码,请参考连接:

https://github.com/987334176/Intelligent_toy/archive/v1.0.zip

 

5、MongoDB数据导入导出

主要有2种导出格式,分别为CSV和JSON。推荐使用JSON,为何呢?

由于导出为csv时,第一行,就是表的字段名,从第二行开始,才是真正的数据!假设数据有5行

所以,导入时,会有6行。那么多出的一行,就是字段名。这显然不是咱们想要的!这个问题,暂时没法解决!

因此推荐使用JSON

 

导出

mongoexport -d 本地数据库名 -c 本地数据表 --type=json -f 表字段(用逗号隔开) -o 本地存储路径

好比:导出bananabase库中的sources中的字段_id,title,nickname,avatar,audio,intro,category,play_count 到sources.json中:

注意:必需要指定字段,不然报错!

mongoexport -d bananabase -c sources --type=json -f _id,title,nickname,avatar,audio,intro,category,play_count -o ./sources.json

 

导入

将本地json文件导入到本地数据库

mongoimport --db 本地数据库名 --collection 本地数据表 --file ~/table.json --type json

好比:假设sources表被删除了,使用sources.json来恢复

mongoimport --db bananabase --collection sources --file sources.json --type json
相关文章
相关标签/搜索