소스 검색

feat: 新闻系统分页显示

SongZihuan 3 년 전
부모
커밋
76bf873711
9개의 변경된 파일210개의 추가작업 그리고 33개의 파일을 삭제
  1. 6 5
      app/news/views.py
  2. 1 1
      app/templates/base.html
  3. 51 0
      app/templates/macro.html
  4. 2 1
      app/templates/news/news.html
  5. 15 5
      app/web.py
  6. 76 20
      setup.py
  7. 15 1
      setup.sql
  8. 8 0
      sql/news.py
  9. 36 0
      tool/page.py

+ 6 - 5
app/news/views.py

@@ -25,16 +25,17 @@ def index():
     if write_form.validate_on_submit():
         if len(write_form.context.data) < 20:
             flash("请输入20个字符以上的内容")
-            return redirect(url_for("news.index"))
+            return redirect(url_for("news.index", page=1))
         user: WebUser = current_user
         if not user.write_news(write_form.context.data):
             abort(500)
-        return redirect(url_for("news.index"))
-    page = request.args.get("page", 1)
-    res, context_list = views.website.get_news(page)
+        return redirect(url_for("news.index", page=1))
+    page = int(request.args.get("page", 1))
+    res, context_list, page_list = views.website.get_news(page)
     if not res:
         abort(404)
-    return render_template("news/news.html", form=write_form, context_list=context_list)
+    return render_template("news/news.html", form=write_form, context_list=context_list,
+                           page_list=page_list, page=f"{page}")
 
 
 def creat_news_website(app_: Flask):

+ 1 - 1
app/templates/base.html

@@ -49,7 +49,7 @@
             <li class="nav-top-item"><a class="nav-top-item" href="{{ url_for('store.index') }}">
                 积分商城 </a></li>
 
-            <li class="nav-top-item"><a class="nav-top-item" href="{{ url_for('news.index') }}">
+            <li class="nav-top-item"><a class="nav-top-item" href="{{ url_for('news.index', page=1) }}">
                 新闻 </a></li>
 
             {% if current_user.is_authenticated %}

+ 51 - 0
app/templates/macro.html

@@ -0,0 +1,51 @@
+{% macro get_page_list(info_lines, page) %}
+    <style>
+        #page-list {
+            position: relative;
+            font-size: 20px;
+            line-height: 25px;
+        }
+
+        li.page-list-item {
+            display: block;
+            float: left;
+            height: 50px;
+            text-align: center;
+            margin: 10px 8px;
+
+        }
+
+        a.page-list-item, a.page-list-item:hover, a.page-list-item:active,
+        a.page-list-item:link, a.page-list-item:visited {
+            text-decoration: underline;
+            padding: 0 10px;
+            border: 1px gray ridge;
+        }
+
+        a.on_page-list-item, a.on_page-list-item:hover, a.on_page-list-item:active,
+        a.on_page-list-item:link, a.on_page-list-item:visited {
+            color: #DC143C;
+        }
+
+        a.out_page-list-item, a.out_page-list-item:hover, a.out_page-list-item:active,
+        a.out_page-list-item:link, a.out_page-list-item:visited {
+            color: black;
+        }
+
+    </style>
+    <ul id="page-list">
+        {% for line in info_lines %}
+            {% if line %}
+                <li class="page-list-item"><a
+                        {% if page == line[0] %}
+                            class="page-list-item on_page-list-item"
+                        {% else %}
+                            class="page-list-item out_page-list-item"
+                        {% endif %}
+                            href="{{ line[1] }}"> {{ line[0] }} </a></li>
+            {% else %}
+                <li class="page-list-item"><a class="page-list-item"> ... </a></li>
+            {% endif %}
+        {% endfor %}
+    </ul>
+{% endmacro %}

+ 2 - 1
app/templates/news/news.html

@@ -11,7 +11,7 @@
 
 {% block content %}
     <h2 class="h2-title"> 发表意见 </h2>
-    <form class="writer clearfix" action="{{ url_for('news.index') }}" method="post">
+    <form class="writer clearfix" action="{{ url_for('news.index', page=1) }}" method="post">
         {{ form.hidden_tag() }}
         {{ form.context(id="writer-context") }}
         {{ form.submit(id="writer-submit", value="提交") }}
@@ -19,4 +19,5 @@
 
     <h2 class="h2-title"> 最新消息 </h2>
     {{ news.get_context_list(context_list) }}
+    {{ macro.get_page_list(page_list, page) }}
 {% endblock %}

+ 15 - 5
app/web.py

@@ -1,19 +1,21 @@
-from sql.store import get_store_item_list, get_store_item, check_order
-
-from flask import Flask
+from flask import Flask, url_for
 from flask_login import current_user
 import datetime
+import math
 
 from conf import Config
 
+from sql.store import get_store_item_list, get_store_item, check_order
+
 from tool.type_ import *
+from tool.page import get_page
 
 from core.garbage import GarbageType
 
 from sql import DBBit
 from sql.db import DB
 from sql.user import find_user_by_name, find_user_by_id
-from sql.news import write_news, get_news
+from sql.news import write_news, get_news, get_news_count
 
 from . import web_user
 from . import web_goods
@@ -123,7 +125,15 @@ class NewsWebsite(WebsiteBase):
         return write_news(context, uid, self.db)
 
     def get_news(self, page: int = 1):
-        return get_news(limit=20, offset=((page - 1) * 20), db=self.db)
+        count = math.ceil(get_news_count(self.db) / 10)
+        if page > count:
+            return False, None, None
+
+        res, news_list = get_news(limit=20, offset=((page - 1) * 10), db=self.db)
+        if not res:
+            return False, None, None
+
+        return True, news_list, get_page("news.index", page, count)
 
 
 class Website(AuthWebsite, StoreWebsite, RankWebsite, NewsWebsite, WebsiteBase):

+ 76 - 20
setup.py

@@ -3,9 +3,18 @@ import sys
 import time
 from typing import Union, List
 
+import faker
+
 print("初始化程序开始执行")
 print("开始检查依赖")
 
+print(r"是否使用 http://pypi.douban.com/simple/ 源")
+use_i = input(r"[Y/n]")
+if use_i == "Y" or use_i == 'y':
+    use_i = r"-i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com"
+else:
+    use_i = ""
+
 try:
     __import__("pip")
 except ImportError:
@@ -13,7 +22,7 @@ except ImportError:
     sys.exit(1)
 else:
     print("依赖 pip 存在")
-    if os.system(f"{sys.executable} -m pip install --upgrade pip") != 0:
+    if os.system(f"{sys.executable} -m pip install {use_i} --upgrade pip") != 0:
         print(f"依赖 pip 更新失败", file=sys.stderr)
     else:
         print(f"依赖 pip 更新成功")
@@ -32,7 +41,7 @@ def check_import(packages: Union[str, List[str]], pips: Union[str, List[str]]):
             print(f"依赖 {package} 存在")
     except ImportError:
         for pip in pips:
-            command = f"{sys.executable} -m pip install {pip}"
+            command = f"{sys.executable} -m pip install {use_i} {pip}"
             print(f"依赖 {pip} 安装: {command}")
             if os.system(command) != 0:
                 print(f"依赖 {pip} 安装失败", file=sys.stderr)
@@ -107,16 +116,14 @@ if input("[Y/n]") != "Y":
 import random
 from tool.login import randomPassword
 
-random_manager = []
-random_normal = []
-loc = ["LOC-A", "LOC-B", "LOC-C"]
+check_import("faker", "Faker")  # matplotlib依赖
+from faker import Faker
 
+fake = Faker(locale='zh_CN')
 
-def random_phone() -> str:
-    r_phone = ""
-    while len(r_phone) < 11:
-        r_phone += f"{random.randint(0, 9)}"
-    return r_phone
+random_manager = []
+random_normal = []
+loc = [fake.street_name() for _ in range(4)]
 
 
 def random_time() -> str:
@@ -133,7 +140,7 @@ def random_time_double() -> tuple[str, str]:
     return mysql_time(min(r_h1, r_h2)), mysql_time(max(r_h1, r_h2))
 
 
-def random_user(r_name, r_passwd, r_phone, r_time, is_manager: int, cur):
+def random_user(r_name, r_passwd, r_phone, r_time, is_manager: int, cur, c_g=0, u_g=0):
     r_score = random.randint(0, 50000) / 100
     r_reputation = random.randint(5, 995)
     r_uid = create_uid(r_name, r_passwd)
@@ -145,21 +152,28 @@ def random_user(r_name, r_passwd, r_phone, r_time, is_manager: int, cur):
     else:
         random_normal.append(r_uid)
         print(f"普通用户: {r_name} {r_passwd} {r_phone} {r_reputation} {r_score} {r_uid}")
+    while c_g > 0:
+        c_g -= 1
+        t2, t1 = random_time_double()
+        random_garbage_c_to_user(r_uid, t1, t2, cur)
+
+    while u_g > 0:
+        u_g -= 1
+        t2, t1 = random_time_double()
+        random_garbage_u_to_user(r_uid, t1, t2, cur)
 
 
 def random_garbage_n(r_time, cur):
     cur.execute(f"INSERT INTO garbage(CreateTime, Flat) VALUES ({r_time}, 0);")
 
 
-def random_garbage_c(r_time, r_time2, cur):
-    user = random.choice(random_normal)
+def random_garbage_c_to_user(user, r_time, r_time2, cur):
     r_loc = random.choice(loc)
     cur.execute(f"INSERT INTO garbage(CreateTime, Flat, UserID, UseTime, GarbageType, Location) "
                 f"VALUES ({r_time}, 1, '{user}', {r_time2}, {random.randint(1, 4)}, '{r_loc}');")
 
 
-def random_garbage_u(r_time, r_time2, cur):
-    user = random.choice(random_normal)
+def random_garbage_u_to_user(user, r_time, r_time2, cur):
     checker = random.choice(random_manager)
     r_loc = random.choice(loc)
     cur.execute(f"INSERT INTO garbage(CreateTime, Flat, UserID, UseTime, GarbageType, Location, "
@@ -168,6 +182,31 @@ def random_garbage_u(r_time, r_time2, cur):
                 f"'{checker}', {random.randint(0, 1)});")
 
 
+def random_garbage_c(r_time, r_time2, cur):
+    user = random.choice(random_normal)
+    random_garbage_c_to_user(user, r_time, r_time2, cur)
+
+
+def random_garbage_u(r_time, r_time2, cur):
+    user = random.choice(random_normal)
+    random_garbage_c_to_user(user, r_time, r_time2, cur)
+
+
+def random_news(c_time, cur):
+    user = random.choice(random_normal)
+    text = f"大家好,我是 {fake.name()}, 我居住在 {fake.street_name()}{fake.street_address()}, 谢谢"
+    cur.execute(f"INSERT INTO context(Context, Author, Time) "
+                f"VALUES ('{text}', '{user}', {c_time});")
+
+
+def random_goods(cur):
+    car = fake.license_plate()
+    quantity = random.randint(0, 20)
+    score = random.randint(10, 200)
+    cur.execute(f"INSERT INTO goods(Name, Quantity, Score) "
+                f"VALUES ('{car}', '{quantity}', {score});")
+
+
 print("步骤1, 注册管理账户[输入q结束]:")
 while True:
     if (name := input("输入用户名:")) == 'q':  # 这里使用了海象表达式, 把赋值运算变成一种表达式
@@ -180,7 +219,7 @@ while True:
         break
 
     if phone == 'x':
-        phone = random_phone()
+        phone = fake.phone_number()
     if creat_time == 'n':
         c_time = mysql_time()
     else:
@@ -197,6 +236,10 @@ while True:
         break
     if (creat_time := input("是否随机时间[n=不随机 y=随机]:")) == 'q':
         break
+    if (w_garbage := input("待检测垃圾个数:")) == 'q':
+        break
+    if (c_garbage := input("已检测垃圾个数:")) == 'q':
+        break
 
     if creat_time == 'n':
         c_time = mysql_time()
@@ -204,14 +247,16 @@ while True:
         c_time = random_time()
 
     if phone == 'x':
-        phone = random_phone()
-    random_user(name, passwd, phone, c_time, 0, cursor)
+        phone = fake.phone_number()
+    w_garbage = int(w_garbage)
+    c_garbage = int(w_garbage)
+    random_user(name, passwd, phone, c_time, 0, cursor, w_garbage, c_garbage)
 
 count = int(input("步骤3, 注册随机管理员账户[输入个数]:"))
 while count > 0:
     name = randomPassword()[:5]
     passwd = randomPassword()
-    phone = random_phone()
+    phone = fake.phone_number()
     c_time = random_time()
     random_user(name, passwd, phone, c_time, 1, cursor)
     count -= 1
@@ -220,7 +265,7 @@ count = int(input("步骤3, 注册随机普通账户[输入个数]:"))
 while count > 0:
     name = randomPassword()[:5]
     passwd = randomPassword()
-    phone = random_phone()
+    phone = fake.phone_number()
     c_time = random_time()
     random_user(name, passwd, phone, c_time, 0, cursor)
     count -= 1
@@ -243,6 +288,17 @@ while count > 0:
     c_time = random_time()
     random_garbage_n(c_time, cursor)
 
+count = int(input("步骤7, 注册随机新闻内容:"))
+while count > 0:
+    count -= 1
+    c_time = random_time()
+    random_news(c_time, cursor)
+
+count = int(input("步骤8, 注册随机商城内容:"))
+while count > 0:
+    count -= 1
+    random_goods(cursor)
+
 sql.commit()
 cursor.close()
 sql.close()

+ 15 - 1
setup.sql

@@ -45,7 +45,6 @@ CREATE TABLE IF NOT EXISTS orders -- 订单
     FOREIGN KEY (UserID) REFERENCES user (UserID)
 );
 
-
 CREATE TABLE IF NOT EXISTS ordergoods -- 订单内容
 (
     OrderGoodsID INT PRIMARY KEY AUTO_INCREMENT,
@@ -56,6 +55,15 @@ CREATE TABLE IF NOT EXISTS ordergoods -- 订单内容
     FOREIGN KEY (GoodsID) REFERENCES Goods (GoodsID)
 );
 
+CREATE TABLE IF NOT EXISTS context
+(
+    ContextID INT PRIMARY KEY AUTO_INCREMENT,
+    Context   TEXT     NOT NULL,
+    Author    CHAR(34) NOT NULL,
+    Time      DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    FOREIGN KEY (Author) REFERENCES user (UserID)
+);
+
 -- 创建视图
 
 DROP VIEW IF EXISTS garbage_n;
@@ -175,6 +183,12 @@ SELECT (TO_DAYS(NOW()) - TO_DAYS(UseTime)) AS days,
 FROM garbage
 WHERE TO_DAYS(NOW()) - TO_DAYS(UseTime) < 30;
 
+DROP VIEW IF EXISTS context_user;
+CREATE VIEW context_user AS
+SELECT context.ContextID, context.Context, context.Time, user.UserID, user.Name
+FROM context
+         JOIN user on context.Author = user.UserID;
+
 -- 创建函数
 CREATE FUNCTION get_avg(num1 int, num2 int)
     RETURNS DECIMAL(5, 4)

+ 8 - 0
sql/news.py

@@ -30,3 +30,11 @@ def get_news(db: DB, limit: Optional[int] = None, offset: Optional[int] = None):
         time: datetime.datetime = re[3]
         res.append((re[0], re[1], re[2], time.strftime("%Y-%m-%d %H:%M")))
     return True, res
+
+
+def get_news_count(db: DB):
+    cur = db.search(columns=["count(ContextID)"], table="context_user")
+    if cur is None:
+        return 0
+    assert cur.rowcount == 1
+    return int(cur.fetchone()[0])

+ 36 - 0
tool/page.py

@@ -0,0 +1,36 @@
+from flask import url_for
+from tool.type_ import *
+
+
+def get_page(url, page: int, count: int):
+    if count <= 9:
+        page_list = [[f"{i + 1}", url_for(url, page=i + 1)] for i in range(count)]
+    elif page <= 5:
+        """
+        [1][2][3][4][5][6][...][count - 1][count]
+        """
+        page_list = [[f"{i + 1}", url_for(url, page=i + 1)] for i in range(6)]
+
+        page_list += [None,
+                      [f"{count - 1}", url_for(url, page=count - 1)],
+                      [f"{count}", url_for(url, page=count)]]
+    elif page >= count - 5:
+        """
+        [1][2][...][count - 5][count - 4][count - 3][count - 2][count - 1][count]
+        """
+        page_list: Optional[list] = [["1", url_for(url, page=1)],
+                                     ["2", url_for(url, page=2)],
+                                     None]
+        page_list += [[f"{count - 5 + i}", url_for(url, page=count - 5 + i), False] for i in range(6)]
+    else:
+        """
+        [1][2][...][page - 2][page - 1][page][page + 1][page + 2][...][count - 1][count]
+        """
+        page_list: Optional[list] = [["1", url_for(url, page=1)],
+                                     ["2", url_for(url, page=2)],
+                                     None]
+        page_list += [[f"{page - 2 + i}", url_for(url, page=page - 2 + i)] for i in range(5)]
+        page_list += [None,
+                      [f"{count - 1}", url_for(url, page=count - 1)],
+                      [f"{count}", url_for(url, page=count)]]
+    return page_list