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

欢迎题留言交流

原文地址:https://www.cnblogs.com/drewgg/p/13321985.html