zoukankan      html  css  js  c++  java
  • Flask搭建APP统一管理平台

    主页效果:

    1.从数据库中获取所有APP的信息,每个卡片上展示APP名称、bundle id、版本构建历史记录,系统类型等构建信息

    2.支持查询筛选,模糊查询

    3.点击历史记录跳转APP历史记录详情页面

    历史详情页面效果:

    页面包含APP名称,对应构建次数的二维码,APP的系统类型及版本信息、扫码、下载

    flashk的框架架构:

    和常见的分层差不多类似:

    1.主要用到的数据、模板、路由

    2.数据是用的DBUtils数据库连接池

    通用app下载页面:

    单次构建版本下载:

     

    贴几个主要的代码:

    css文件,js文件,感兴趣的可以留言交流。

     app_main.py:

    from app.dao import read_sql as sql
    from flask import Flask, render_template
    
    app = Flask('app')
    
    
    @app.route('/')
    def get_index():
        mysql_l = sql.deal_mysql('get_app_new.sql')
        return render_template('/post/app_main_detail.html', data=mysql_l, len_data=len(mysql_l))
    
    
    @app.route('/<app_name>')
    def get_index_app(app_name):
        if app_name:
            na_app = list([app_name])
            mysql_l = sql.deal_mysql('get_app_new_search.sql', na_app)
        else:
            mysql_l = sql.deal_mysql('get_app_new.sql')
        return render_template('/post/app_main_detail.html', data=mysql_l, len_data=len(mysql_l))
    
    
    @app.route('/app_detail/<app_name>/<path:qr_name>')
    def get_app_detail(app_name, qr_name):
        name_app = list([app_name])
        app_detail = []
        android_qa = sql.deal_mysql('get_android_qa.sql', name_app)
        android_online = sql.deal_mysql('get_android_online.sql', name_app)
        ios_test = sql.deal_mysql('get_ios_test.sql', name_app)
        ios_product = sql.deal_mysql('get_ios_product.sql', name_app)
        app_detail.append(android_qa)
        app_detail.append(android_online)
        app_detail.append(ios_test)
        app_detail.append(ios_product)
    
        return render_template('/post/app_detail.html', data=app_detail, q_name=qr_name, name=app_name)
    
    
    if __name__ == '__main__':
        app.run(host='0.0.0.0', port='9000', debug=True)

    app_detail.html【含3d效果的css】

    <!DOCTYPE html>
    <html lang="en">
    
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <link rel="stylesheet" type="text/css" href="https://pkgcdn.thecover.cn/pkg/cover/css/app_manger/1.5.0/3d.css">
            <link rel="stylesheet" type="text/css" href="https://pkgcdn.thecover.cn/pkg/cover/css/app_manger/1.5.0/htmleaf-demo.css">
            <link rel="stylesheet" type="text/css" href="https://pkgcdn.thecover.cn/pkg/cover/css/app_manger/1.5.0/tabs-basic.css">
        </head>
    
        <body>
            <div class="container">
                <div class="card">
                    <div class="img" align="center" >
                        <div style="color: #1183fb;">
                            <h3>{{name}}</h3>
                        </div>
                        <img id="show_img" width="255", height="255" src="{{q_name}}"/>
                        <div style="color: #32a3b1;">
                            <h4> 扫描二维码下载[浏览器扫码]</h4>
                        </div>
    
                    </div>
                    <div class="contentBx" align="right">
                    </div>
                    <div class="htmleaf-container">
                        <div class="tabs-basic">
                            <ul>
                                <li>
                                    <a class="tab-active" data-index="0" href="#">Android(测)</a>
                                </li>
                                <li>
                                    <a data-index="1" href="#">Android(正)</a>
                                </li>
                                <li>
                                    <a data-index="2" href="#">iOS(测)</a>
                                </li>
                                 <li>
                                    <a data-index="3" href="#">iOS(正)</a>
                                </li>
                            </ul>
    
                            <div class="tabs-content-placeholder">
                                <div class="tab-content-active">
                                    <table border="0" cellpadding="2" style="border-collapse:collapse;margin-top:1px" align="center">
                                         <tr height="28px">
                                             <td  align="center"><font size="1"><strong>版本号</strong></font></td>
                                             <td  align="center"><font size="1"><strong>次数</strong></font></td>
                                             <td  align="center"><font size="1"><strong>类型</strong></font></td>
                                             <td  align="center"><font size="1"><strong>构建时间</strong></font></td>
                                             <td  colspan="100"  align="center"><font size="1"><strong>操作</strong></font></td>
                                         </tr>
                                        {% for i in data[0] %}
                                            <tr>
                                                <td align="center"><font size="1">{{i[1]}}</font></td>
                                                <td align="center"><font size="1">{{i[2]}}</font></td>
                                                <td align="center"><font size="1">{{i[3]}}</font></td>
                                                <td align="center"><font size="1">{{i[6]}}</font></td>
                                                <td><a class="ercode-img" data-img="{{i[4]}}"><font size="1" >扫码</font></a></td>
                                                <td><a href="{{i[5]}}"><font size="1">下载</font></a></td>
                                            </tr>
                                        {% endfor %}
                                    </table>
                                </div>
    
                                <div>
                                    <table border="0" cellpadding="2" style="border-collapse:collapse;margin-top:1px" align="center">
                                         <tr height="28px">
                                             <td align="center"><font size="1"><strong>版本号</strong></font></td>
                                             <td align="center"><font size="1"><strong>次数</strong></font></td>
                                             <td align="center"><font size="1"><strong>类型</strong></font></td>
                                             <td align="center"><font size="1"><strong>构建时间</strong></font></td>
                                             <td colspan="2" align="center"><font size="1"><strong>操作</strong></font></td>
                                         </tr>
                                        {% for i in data[1] %}
                                            <tr>
                                                <td align="center"><font size="1">{{i[1]}}</font></td>
                                                <td align="center"><font size="1">{{i[2]}}</font></td>
                                                <td align="center"><font size="1">{{i[3]}}</font></td>
                                                <td align="center"><font size="1">{{i[6]}}</font></td>
                                                <td align="right"><a class="ercode-img" data-img="{{i[4]}}"><font size="1">扫码</font></a></td>
                                                <td align="left"><a href="{{i[5]}}"><font size="1">下载</font></a></td>
                                            </tr>
                                        {% endfor %}
                                    </table>
                                </div>
    
                                <div>
                                    <table border="0" cellpadding="2" style="border-collapse:collapse;margin-top:1px" align="center">
                                         <tr height="28px">
                                              <td width="50" height="5" align="center"><font size="1"><strong>版本号</strong></font></td>
                                              <td width="80" height="5" align="center"><font size="1"><strong>次数</strong></font></td>
                                              <td width="40" height="5" align="center"><font size="1"><strong>类型</strong></font></td>
                                              <td width="160" height="5" align="center"><font size="1"><strong>构建时间</strong></font></td>
                                             <td width="80" height="5" align="center"><font size="1"><strong>操作</strong></font></td>
                                         </tr>
                                        {% for i in data[2] %}
                                            <tr>
                                                <td align="center"><font size="1">{{i[1]}}</font></td>
                                                <td align="center"><font size="1">{{i[2]}}</font></td>
                                                <td align="center"><font size="1">{{i[3]}}</font></td>
                                                <td align="center"><font size="1">{{i[6]}}</font></td>
                                                <td align="center"><a class="ercode-img" data-img="{{i[4]}}"><font size="1">扫码</font></a></td>
                                            </tr>
                                        {% endfor %}
                                    </table>
                                </div>
    
                                <div>
                                    <table border="0" cellpadding="2" style="border-collapse:collapse;margin-top:1px" align="center">
                                         <tr height="28px">
                                              <td width="50" height="5" align="center"><font size="1"><strong>版本号</strong></font></td>
                                              <td width="80" height="5" align="center"><font size="1"><strong>次数</strong></font></td>
                                              <td width="40" height="5" align="center"><font size="1"><strong>类型</strong></font></td>
                                              <td width="160" height="5" align="center"><font size="1"><strong>构建时间</strong></font></td>
                                             <td width="80" height="5" align="center"><font size="1"><strong>操作</strong></font></td>
                                         </tr>
                                        {% for i in data[3] %}
                                            <tr>
                                                <td align="center"><font size="1">{{i[1]}}</font></td>
                                                <td align="center"><font size="1">{{i[2]}}</font></td>
                                                <td align="center"><font size="1">{{i[3]}}</font></td>
                                                <td align="center"><font size="1">{{i[6]}}</font></td>
                                                <td align="center"><a class="ercode-img" data-img="{{i[4]}}"><font size="1">扫码</font></a></td>
                                            </tr>
                                        {% endfor %}
                                    </table>
                                </div>
                            </div>
                        </div>
                    </div>
                     <script src="https://pkgcdn.thecover.cn/pkg/cover/js/app_manger/1.5.0/jquery.js"></script>
                    <script type="text/javascript">
    
                        $(document).ready(function() {
    
                            var widget = $('.tabs-basic');
    
                            var tabs = widget.find('ul a'),
                                content = widget.find('.tabs-content-placeholder > div');
    
                            tabs.on('click', function (e) {
    
                                e.preventDefault();
    
                                // Get the data-index attribute, and show the matching content div
    
                                var index = $(this).data('index');
    
                                tabs.removeClass('tab-active');
                                content.removeClass('tab-content-active');
    
                                $(this).addClass('tab-active');
                                content.eq(index).addClass('tab-content-active');
    
                            });
    
                        });
                        $('.ercode-img').on('click', function(){
                            var img = $(this).attr('data-img');
                            $('#show_img').attr('src', img);
                        })
                    </script>
                </div>
            </div>
        </body>
    
    </html>

    app_main_detail.html【css含搜索动画效果、卡片浮动效果】

    <!DOCTYPE html>
    <html lang="zn">
        <head>
            <meta charset="UTF-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
            <meta name="viewport" content="initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no">
            <link rel="stylesheet" href="https://pkgcdn.thecover.cn/pkg/cover/css/app_manger/1.5.0/zui.min.css">
            <script src="https://pkgcdn.thecover.cn/pkg/cover/js/app_manger/1.5.0/jquery.js"></script>
            <link rel="stylesheet" href="https://pkgcdn.thecover.cn/pkg/cover/css/app_manger/1.5.0/source_end.css" type="text/css" media="screen">
            <link rel="stylesheet" href="https://pkgcdn.thecover.cn/pkg/cover/css/app_manger/1.0.0/normalize.css" type="text/css" media="screen">
            <link rel="stylesheet" href="https://pkgcdn.thecover.cn/pkg/cover/css/app_manger/1.2.0/search-form.css" type="text/css" media="screen">
    
         <title>Cover-App Testing Platform</title>
    
        </head>
        <body>
           <div class="title">
            <h1> 封面APP统一管理平台 </h1>
            <p> 封面传媒融媒体APP、内部APP、封巢、直播等应用统一管理平台</p>
           </div>
           <div>
               <section class="htmleaf-container">
                    <form onsubmit="submitFn(this, event); " method = "post">
                        <div class="search-wrapper">
                            <div class="input-holder">
                                <input type="text" class="search-input" placeholder="请输入APP名称,支持模糊查询" />
                                <button class="search-icon" onclick="searchToggle(this, event);"><span></span></button>
                            </div>
                            <span class="close" onclick="searchToggle(this, event);"></span>
                            <div class="result-container">
                            </div>
                        </div>
    
                    </form>
               </section>
           </div>
    
           <script type="text/javascript">
            function searchToggle(obj, evt){
                var container = $(obj).closest('.search-wrapper');
    
                if(!container.hasClass('active')){
                      container.addClass('active');
                      evt.preventDefault();
                }
                else if(container.hasClass('active') && $(obj).closest('.input-holder').length == 0){
                      container.removeClass('active');
                      // clear input
                      container.find('.search-input').val('');
                      // clear and hide result container when we press close
                      container.find('.result-container').fadeOut(100, function(){$(this).empty();});
                }
            }
    
            function submitFn(obj, evt){
                value = $(obj).find('.search-input').val().trim();
                if(!value.length){
                     window.location.href = "/";
                }
                else{
                    window.location.href = "/" + value;
                }
                evt.preventDefault();
            }
        </script>
    
          <div class="col col-12" data-grid="12" data-row="4" style="top: 95px">
           <div id="block1261" class="block" >
              {% for i in range(len_data) %}
                  {% if i % 4 == 0 %}
                      <div class="see-wrap">
                          <div class="container">
                              <div class="row">
                                  <div class="col-md-3">
                                      <div class="see-box see">
                                          <div class="see-top">
                                              <h4> {{data[i][0]}} </h4>
                                              <p> bundle id:<br>{{data[i][3]}} </p>
                                              <a href="/app_detail/{{data[i][0]}}/{{data[i][9]}}" target="_blank">历史记录</a>
                                          </div>
                                          <div class="see-bottom">
                                              <p><em></em><span>For Build {{data[i][1]}} ({{data[i][2]}})</span> </p>
                                              <p><em></em><span>构建版本: {{data[i][4]}}(id-{{data[i][5]}})</span> </p>
                                              <p><em></em><span>构建时间: {{data[i][6]}}</span> </p>
                                              <p><em></em><span>更新环境: {{data[i][8]}}</span> </p>
                                         </div>
                                      </div>
                                  </div>
                  {% elif i% 4 == 3 %}
                           <div class="col-md-3">
                               <div class="see-box see">
                                   <div class="see-top">
                                      <h4> {{data[i][0]}} </h4>
                                      <p> bundle id:<br>{{data[i][3]}} </p>
                                      <a href="/app_detail/{{data[i][0]}}/{{data[i][9]}}" target="_blank">历史记录</a>
                                    </div>
                                   <div class="see-bottom">
                                      <p><em></em><span>For Build {{data[i][1]}} ({{data[i][2]}})</span> </p>
                                      <p><em></em><span>构建版本: {{data[i][4]}}(id-{{data[i][5]}})</span> </p>
                                      <p><em></em><span>构建时间: {{data[i][6]}}</span> </p>
                                      <p><em></em><span>更新环境: {{data[i][8]}}</span> </p>
                                   </div>
                               </div>
                           </div>
                        </div>
                      </div>
                   </div>
                  {% else %}
                    <div class="col-md-3">
                       <div class="see-box see">
                           <div class="see-top">
                              <h4> {{data[i][0]}} </h4>
                              <p> bundle id:<br>{{data[i][3]}} </p>
                              <a href="/app_detail/{{data[i][0]}}/{{data[i][9]}}" target="_blank">历史记录</a>
                            </div>
                           <div class="see-bottom">
                              <p><em></em><span>For Build {{data[i][1]}} ({{data[i][2]}})</span> </p>
                              <p><em></em><span>构建版本: {{data[i][4]}}(id-{{data[i][5]}})</span> </p>
                              <p><em></em><span>构建时间: {{data[i][6]}}</span> </p>
                              <p><em></em><span>更新环境: {{data[i][8]}}</span> </p>
                           </div>
                       </div>
                   </div>
                  {% endif %}
              {% endfor %}
           </div>
          </div>
        </body>
    </html>

    flask_mysql.py

    import pymysql
    from DBUtils.PooledDB import PooledDB
    from app.dao import db_config as config
    
    
    class Database:
        def __init__(self, *db):
            # mysql数据库
            self.host = config.mysqlInfo['host']
            self.port = config.mysqlInfo['port']
            self.user = config.mysqlInfo['user']
            self.pwd = config.mysqlInfo['passwd']
            self.db = config.mysqlInfo['db']
            self.charset = config.mysqlInfo['charset']
            self.create_pool()
    
        def create_pool(self):
            self.Pool = PooledDB(creator=pymysql, mincached=2, maxcached=5, maxshared=3, maxconnections=6, blocking=True, host=self.host, port=self.port,
                                 user=self.user, password=self.pwd, database=self.db, charset=self.charset)
    
        def get_connect(self):
            self.conn = self.Pool.connection()
            cur = self.conn.cursor()
            if not cur:
                raise NameError("数据库连接不上")
            else:
                return cur
    
        # 查询sql
        def exec_query(self, sql):
            cur = self.get_connect()
            cur.execute(sql)
            re_list = cur.fetchall()
            cur.close()
            self.conn.close()
            return re_list
    
        # 非查询的sql,增删改
        def exec_no_query(self, sql):
            cur = self.get_connect()
            cur.execute(sql)
            self.conn.commit()
            cur.close()
            self.conn.close()
    
        # 显示查询中的第一条记录
        def show_first(self, sql):
            cur = self.get_connect()
            cur.execute(sql)
            result_first = cur.fetchone()
            cur.close()
            self.conn.close()
            return result_first
    
        # 显示查询出的所有结果
        def show_all(self, sql):
            cur = self.get_connect()
            cur.execute(sql)
            result_all = cur.fetchall()
            cur.close()
            self.conn.close()
            return result_all
    
    
    if __name__ == "__main__":
        d = Database()
        sql = """
        """
        for i in range(100):
            a = d.show_all(sql)
            print(a)

    read_sql.py

    # coding = utf-8
    # 禅道项目度量--读取sql脚本
    
    import os
    from app.dao import flask_mysql as mysql
    
    pl = os.getcwd().split('cover_app_platform')
    path_pl = pl[0] + "cover_app_platform\app\dao\sql_scripts\"
    
    
    # 读取sql脚本
    def read_sql(f):
        """
        :param f: 需要读取sql脚本的文件
        :return: 返回读取后的sql语句
        """
        f_path = path_pl + f
    
        try:
            fi = open(f_path, "r", encoding='UTF-8')
            fp = fi.readlines()
            fi.close()
            sql_script = ''
            for i in fp:
                sql_script += i
            return sql_script
        except FileNotFoundError as ep:
            return ep
    
    
    def deal_mysql(f, pa=''):
        """
        :param f:
        :param pa:
        :return:
        """
        d = mysql.Database()
        sql = read_sql(f)
        print(pa)
        if len(pa) != 0:
            for i in pa:
                sql = sql.replace('@@@@', i)
        results = d.show_all(sql)
        tl = list(results)
        return tl

    欢迎题留言交流

  • 相关阅读:
    Redis on Spark:Task not serializable
    一次Spark应用程序参数优化案例
    Spark性能优化(2)——广播变量、本地缓存目录、RDD操作、数据倾斜
    Spark性能优化(1)——序列化、内存、并行度、数据存储格式、Shuffle
    Java – Convert IP address to Decimal Number
    Java IP地址字符串与BigInteger的转换, 支持IPv6
    Spark性能优化(2)——广播变量、本地缓存目录、RDD操作、数据倾斜
    Android Matrix类以及ColorMatri
    OpenGL中shader使用
    Android应用程序与SurfaceFlinger服务之间的共享UI元数据(SharedClient)的创建过程分析 .
  • 原文地址:https://www.cnblogs.com/drewgg/p/13321985.html
Copyright © 2011-2022 走看看