Преглед изворни кода

feat: 支持在线查看榜单

SongZihuan пре 3 година
родитељ
комит
47f2d77df2

+ 0 - 0
app/__init__.py


+ 82 - 0
app/ranking.py

@@ -0,0 +1,82 @@
+from flask import Flask, render_template, Blueprint
+
+import conf
+from sql.db import DB
+from tool.type_ import Optional, List, Tuple
+
+
+class RankWebsite:
+    main = Blueprint("main", __name__)
+
+    def __init__(self, db: DB):
+        self._db = db
+        self.app: Flask = Flask(__name__)
+        self.app.register_blueprint(self.main)
+
+    def get_rank(self, order_by: str = "DESC") -> Optional[List[Tuple]]:
+        cur = self._db.search((f"SELECT UserID, Name, Score, Reputation "
+                               f"FROM user "
+                               f"WHERE IsManager = 0 "
+                               f"ORDER BY Reputation {order_by}, Score {order_by}, UserID {order_by} "
+                               f"LIMIT 200;"))
+
+        print(f"SELECT UserID, Name, Score, Reputation "
+              f"FROM user "
+              f"WHERE IsManager = 0 "
+              f"ORDER BY Reputation {order_by}, Score {order_by}, UserID {order_by}"
+              f"LIMIT 200;")
+
+        if cur is None:
+            return None
+        res = []
+        for index in range(cur.rowcount):
+            i = cur.fetchone()
+            res.append((f"NO.{index + 1}", i[1], i[0][:conf.tk_show_uid_len], str(i[3]), str(i[2])))
+        return res
+
+    @staticmethod
+    @main.route('/')
+    def index():
+        global website
+        return render_template("index.html", loc=conf.base_location)
+
+    @staticmethod
+    @main.route('/rank_up')
+    def rank_up():
+        global website
+        head = ["#", "UserName", "UserID", "Reputation", "Score"]
+        data = website.get_rank("DESC")
+        return render_template("ranking.html", rank_head=head, rank_info=data, ranking_name="高分榜")
+
+    @staticmethod
+    @main.route('/rank_down')
+    def rank_down():
+        global website
+        head = ["#", "UserName", "UserID", "Reputation", "Score"]
+        data = website.get_rank("ASC")
+        return render_template("ranking.html", rank_head=head, rank_info=data, ranking_name="警示榜")
+
+    @staticmethod
+    @main.app_errorhandler(404)
+    def error_404(e):
+        return render_template("error.html", error_code="404", error_info=e), 404
+
+    def run(self):
+        self.app.run()
+
+
+website: Optional[RankWebsite] = None
+
+
+def creat_ranking_website(db: DB):
+    global website
+    if website is not None:
+        return website, website.app
+    website = RankWebsite(db)
+    return website, website.app
+
+
+if __name__ == '__main__':
+    mysql_db = DB()
+    web, app = creat_ranking_website(mysql_db)
+    web.run()

+ 13 - 0
app/static/styles/base.css

@@ -0,0 +1,13 @@
+html {
+    font-size: 15px;
+    font-family: 'Open Sans', sans-serif;
+    background-color: #F0FFF0;
+}
+
+h1, h2 {
+    text-align: center;
+}
+
+div.welcome {
+    text-align: center;
+}

+ 62 - 0
app/static/styles/nav.css

@@ -0,0 +1,62 @@
+#nav {
+    background-color: #F08080;
+}
+
+#nav ul {
+    border-width: 5px;
+    border-style: ridge;
+    border-color: #F08080;
+
+    height: 30px;
+    margin: 25px 0 30px 0;
+    list-style: none;
+}
+
+#nav li {
+    margin: 0 10px 0;
+    height: 30px;
+    text-align: center;
+    line-height: 30px;
+    display: inline;
+}
+
+#nav a.nav-item {
+    color: #ffffff;
+    text-decoration: none;
+    padding: 20px 30px;
+    display: inline;
+}
+
+#nav h1.nav-h1 {
+    border-width: 5px;
+    border-style: ridge;
+    border-color: #F08080;
+
+    color: #000000;
+    text-decoration: none;
+    padding: 15px 40px;
+    display: inline;
+
+    background-color: #ffffff;
+}
+
+#nav a.nav-item:hover {
+    border-width: 5px;
+    border-style: ridge;
+    border-color: #F08080;
+
+    background-color: #F08080;
+    padding: 12px 25px; /* 修改宽度, 防止后面的元素移动 */
+}
+
+#nav h1.nav-h1:hover {
+    border-width: 5px;
+    border-style: ridge;
+    border-color: #F08080;
+
+    color: #ffffff;
+    text-decoration: none;
+    padding: 15px 40px;
+
+    background-color: #000000;
+}

+ 28 - 0
app/static/styles/ranking.css

@@ -0,0 +1,28 @@
+.rank_table {
+    background-color: #E9967A;
+    font-size: 17px;
+}
+
+table.rank_table {
+    border-width: 5px;
+    border-color: #F4A460;
+    border-style: ridge;
+
+    padding: 5px 5px;
+    margin: 5px 5% 5px;
+    width: 90%;
+}
+
+tr.rank_table {
+    text-align: left;
+
+}
+
+td.rank_table {
+    text-align: left;
+}
+
+caption.rank_table {
+    font-size: 30px;
+    background-color: #F0FFF0;
+}

+ 39 - 0
app/templates/base.html

@@ -0,0 +1,39 @@
+{% import "macro.html" as macro %}
+
+<!DOCTYPE html>
+<html lang="ch">
+<head>
+    <meta charset="utf-8">
+
+    {% block font %}
+        <link rel="preconnect" href="https://fonts.googleapis.com">
+        <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+        <link href="https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,500;1,300&display=swap"
+              rel="stylesheet">
+    {% endblock %}
+
+    {% block style %}
+        <link href="{{ url_for('static', filename='styles/base.css') }}" rel="stylesheet">
+        <link href="{{ url_for('static', filename='styles/nav.css') }}" rel="stylesheet">
+    {% endblock %}
+
+    <title> HG: {% block  title %} HGSSystem {% endblock %} </title>
+</head>
+
+<body>
+
+{% block navbar %}
+    <nav id="nav">
+        <ul>
+            <li><h1 class="nav-h1"> HGSSystem-在线榜单 </h1></li>
+            <li><a class="nav-item" href="{{ url_for('main.index') }}">首页</a></li>
+            <li><a class="nav-item" href="{{ url_for('main.rank_up') }}">高分榜</a></li>
+            <li><a class="nav-item" href="{{ url_for('main.rank_down') }}">警示榜</a></li>
+        </ul>
+    </nav>
+{% endblock %}
+
+{% block content %}{% endblock %}
+
+</body>
+</html>

+ 10 - 0
app/templates/error.html

@@ -0,0 +1,10 @@
+{% extends "base.html" %}
+
+{% block title %} {{ error_code }}-错误 {% endblock %}
+
+{% block content %}
+    {{ super() }}
+
+    <h2>遭遇错误</h2>
+    <p style="text-align: center"> {{ error_info }} </p>
+{% endblock %}

+ 13 - 0
app/templates/index.html

@@ -0,0 +1,13 @@
+{% extends "base.html" %}
+
+{% block title %} 排行榜 {% endblock %}
+
+{% block content %}
+    {{ super() }}
+
+    <div class="welcome">
+        <h2>欢迎</h2>
+        <p>欢迎查阅 {{ loc }} 地区的垃圾分类榜单</p>
+        <p>目前支持的榜单包括:高分榜和警示榜</p>
+    </div>
+{% endblock %}

+ 0 - 0
app/templates/macro.html


+ 26 - 0
app/templates/rank_macro.html

@@ -0,0 +1,26 @@
+{% macro get_rank_head(heads) %}
+    <thead class="rank_table">
+    <tr class="rank_table">
+        {% for head in heads %}
+            <th class="rank_table" scope="col">{{ head|safe }}</th>
+        {% endfor %}
+    </tr>
+    </thead>
+{% endmacro %}
+
+{% macro _get_rank(infos) %}
+    <tr class="rank_table">
+        <th class="rank_table" scope="row"> {{ infos[0]|safe }} </th>
+        {% for info in infos[1:] %}
+            <td class="rank_table"> {{ info|safe }} </td>
+        {% endfor %}
+    </tr>
+{% endmacro %}
+
+{% macro get_rank(info_lines) %}
+    <tbody class="rank_table">
+    {% for line in info_lines %}
+        {{ _get_rank(line) }}
+    {% endfor %}
+    </tbody>
+{% endmacro %}

+ 25 - 0
app/templates/ranking.html

@@ -0,0 +1,25 @@
+{% extends "base.html" %}
+{% import "rank_macro.html" as rank %}
+
+{% block title %} 排行榜 {% endblock %}
+
+{% block style %}
+    {{ super() }}
+    <link href="{{ url_for('static', filename='styles/ranking.css') }}" rel="stylesheet">
+{% endblock %}
+
+{% block content %}
+    {{ super() }}
+
+    <h2>{{ ranking_name }}</h2>
+    {% if rank_info and rank_head %}
+        <div>
+            <table class="rank_table">
+                {{ rank.get_rank_head(rank_head) }}
+                {{ rank.get_rank(rank_info) }}
+            </table>
+        </div>
+    {% else %}
+        <p> 排行榜获取失败 </p>
+    {% endif %}
+{% endblock %}

+ 2 - 2
sql/db.py

@@ -1,9 +1,9 @@
 import conf
-from base_db import DBBit, DBException, DBCloseException, DBDataException, DBDoneException  # 导入必要的内容
+from .base_db import DBBit, DBException, DBCloseException, DBDataException, DBDoneException  # 导入必要的内容
 
 if conf.database.upper() == 'MYSQL':
     try:
-        from mysql_db import MysqlDB
+        from .mysql_db import MysqlDB
     except ImportError:
         print("Can not import mysqlDB")
         raise

+ 1 - 1
sql/mysql_db.py

@@ -1,7 +1,7 @@
 import pymysql
 import threading
 from conf import MYSQL_URL, MYSQL_NAME, MYSQL_PASSWORD
-from base_db import Database, DBException, DBCloseException
+from .base_db import Database, DBException, DBCloseException
 from tool.type_ import *
 
 

+ 1 - 1
tk_ui/ranking.py

@@ -51,7 +51,7 @@ class RankingStationBase(metaclass=abc.ABCMeta):
         cur = self._db.search((f"SELECT UserID, Name, Score, Reputation "
                                f"FROM user "
                                f"WHERE IsManager = 0 "
-                               f"ORDER BY reputation DESC, score DESC "
+                               f"ORDER BY Reputation DESC, Score DESC "
                                f"LIMIT {limit} OFFSET {offset};"))
         if cur is None or cur.rowcount == 0:
             return False, []