From 4aebebdb4b10918bb7a2a23399c206fb587dba09 Mon Sep 17 00:00:00 2001 From: redoing <2677915375@qq.com> Date: Mon, 22 Apr 2024 00:54:28 +0800 Subject: [PATCH 001/131] =?UTF-8?q?feature:#=E4=BA=8C=E6=AC=A1=E5=BC=80?= =?UTF-8?q?=E5=8F=91,=E6=96=B0=E5=A2=9E=E6=BC=AB=E7=94=BB=E7=AE=A1?= =?UTF-8?q?=E7=90=86,=E7=94=A8=E4=BA=8E=E5=8A=A0=E8=BD=BD=E6=9C=AC?= =?UTF-8?q?=E5=9C=B0=E6=BC=AB=E7=94=BB=E6=9F=A5=E7=9C=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- applications/config.py | 2 +- applications/models/__init__.py | 1 + applications/models/comic.py | 35 +++++ applications/schemas/__init__.py | 1 + applications/schemas/comic.py | 25 +++ applications/view/__init__.py | 2 + applications/view/admin/__init__.py | 10 ++ applications/view/admin/comic.py | 90 +++++++++++ applications/view/system/index.py | 8 +- plugins/comic/__init__.json | 5 + plugins/comic/__init__.py | 13 ++ plugins/comic/index.py | 8 + plugins/comic/templates/index.html | 12 ++ templates/admin/comic/add.html | 89 +++++++++++ templates/admin/comic/index.html | 227 ++++++++++++++++++++++++++++ 16 files changed, 526 insertions(+), 4 deletions(-) create mode 100644 applications/models/comic.py create mode 100644 applications/schemas/comic.py create mode 100644 applications/view/admin/__init__.py create mode 100644 applications/view/admin/comic.py create mode 100644 plugins/comic/__init__.json create mode 100644 plugins/comic/__init__.py create mode 100644 plugins/comic/index.py create mode 100644 plugins/comic/templates/index.html create mode 100644 templates/admin/comic/add.html create mode 100644 templates/admin/comic/index.html diff --git a/.gitignore b/.gitignore index 3e90094..ce42ecb 100644 --- a/.gitignore +++ b/.gitignore @@ -88,7 +88,7 @@ celerybeat-schedule *.sage.py # Environments -.env +.flaskenv .venv env/ venv/ diff --git a/applications/config.py b/applications/config.py index e8e3bdf..8bad316 100644 --- a/applications/config.py +++ b/applications/config.py @@ -62,7 +62,7 @@ class BaseConfig: MAIL_DEFAULT_SENDER = MAIL_USERNAME # 插件配置,填写插件的文件名名称,默认不启用插件。 - PLUGIN_ENABLE_FOLDERS = [] + PLUGIN_ENABLE_FOLDERS = ['helloworld', 'comic'] # 配置多个数据库连接的连接串写法示例 # HOSTNAME: 指数据库的IP地址、USERNAME:指数据库登录的用户名、PASSWORD:指数据库登录密码、PORT:指数据库开放的端口、DATABASE:指需要连接的数据库名称 diff --git a/applications/models/__init__.py b/applications/models/__init__.py index d94b265..5549b9e 100644 --- a/applications/models/__init__.py +++ b/applications/models/__init__.py @@ -8,3 +8,4 @@ from .admin_role_power import role_power from .admin_user import User from .admin_user_role import user_role from .admin_mail import Mail +from .comic import Comic, Chapter, ChapterImage diff --git a/applications/models/comic.py b/applications/models/comic.py new file mode 100644 index 0000000..7c4acef --- /dev/null +++ b/applications/models/comic.py @@ -0,0 +1,35 @@ +import datetime +from applications.extensions import db + + +class Comic(db.Model): + __tablename__ = 'comic' + id = db.Column(db.Integer, primary_key=True, comment='漫画ID') + name = db.Column(db.String(255), comment='漫画名称') + author_id = db.Column(db.Integer, comment='漫画作者ID') + description = db.Column(db.String(255), comment='描述') + cover_image = db.Column(db.String(255), comment='封面') + release_date = db.Column(db.DateTime, comment='发布日期') + status = db.Column(db.Integer, comment='状态:0-连载中,1-已完结') + created_at = db.Column(db.DateTime, default=datetime.datetime.now, comment='创建时间') + updated_at = db.Column(db.DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now, comment='更新时间') + + +class Chapter(db.Model): + __tablename__ = 'chapter' + id = db.Column(db.Integer, primary_key=True, comment='章节id') + comic_id = db.Column(db.Integer, comment='漫画ID') + name = db.Column(db.String(255), comment='章节名称') + chapter_number = db.Column(db.Integer, comment='章节编号') + release_date = db.Column(db.DateTime, comment='发布日期') + image_url = db.Column(db.String(255), comment='章节封面') + created_at = db.Column(db.DateTime, default=datetime.datetime.now, comment='创建时间') + updated_at = db.Column(db.DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now, comment='更新时间') + + +class ChapterImage(db.Model): + __tablename__ = 'chapter_image' + id = db.Column(db.Integer, primary_key=True, comment='图片id') + chapter_id = db.Column(db.Integer, comment='章节id') + url = db.Column(db.String(255), comment='图片URL') + order = db.Column(db.Integer, comment='排序') diff --git a/applications/schemas/__init__.py b/applications/schemas/__init__.py index 56aa9d0..7c6f86d 100644 --- a/applications/schemas/__init__.py +++ b/applications/schemas/__init__.py @@ -6,3 +6,4 @@ from .admin_dept import DeptSchema from .admin_log import LogOutSchema from .admin_photo import PhotoOutSchema from .admin_mail import MailOutSchema +from .comic import ComicSchema, ChapterSchema diff --git a/applications/schemas/comic.py b/applications/schemas/comic.py new file mode 100644 index 0000000..5150c0d --- /dev/null +++ b/applications/schemas/comic.py @@ -0,0 +1,25 @@ +from applications.extensions import ma +from marshmallow import fields + + +class ComicSchema(ma.Schema): + id = fields.Integer + name = fields.Str() + author_id = fields.Str() + description = fields.Str() + cover_image = fields.Str() + release_date = fields.DateTime() + status = fields.Integer + create_at = fields.DateTime() + update_at = fields.DateTime() + + +class ChapterSchema(ma.Schema): + id = fields.Integer + comic_id = fields.Str() + name = fields.Str() + chapter_number = fields.Str() + release_date = fields.DateTime() + image_url = fields.Str() + create_at = fields.DateTime() + update_at = fields.DateTime() diff --git a/applications/view/__init__.py b/applications/view/__init__.py index e1fb713..d4c6d75 100644 --- a/applications/view/__init__.py +++ b/applications/view/__init__.py @@ -1,7 +1,9 @@ from applications.view.system import register_system_bps from applications.view.plugin import register_plugin_views +from applications.view.admin import register_admin_bps def init_bps(app): register_system_bps(app) register_plugin_views(app) + register_admin_bps(app) diff --git a/applications/view/admin/__init__.py b/applications/view/admin/__init__.py new file mode 100644 index 0000000..46e8bd2 --- /dev/null +++ b/applications/view/admin/__init__.py @@ -0,0 +1,10 @@ +from flask import Blueprint, Flask +from applications.view.admin.comic import bp as comic + +admin_bp = Blueprint('admin', __name__, url_prefix='/admin') + + +def register_admin_bps(app: Flask): + admin_bp.register_blueprint(comic) + + app.register_blueprint(admin_bp) diff --git a/applications/view/admin/comic.py b/applications/view/admin/comic.py new file mode 100644 index 0000000..3160bee --- /dev/null +++ b/applications/view/admin/comic.py @@ -0,0 +1,90 @@ +import logging +from datetime import datetime + +from flask import Blueprint, render_template, request,session + +from applications.common.utils.http import table_api, fail_api, success_api +from applications.common.utils.rights import authorize +from applications.common.utils.validate import str_escape +from applications.extensions import db +from applications.models import Comic, User + +bp = Blueprint('comics', __name__, url_prefix='/comics') + + +@bp.get("/") +@authorize("admin:comic:index") +def index(): + return render_template('admin/comic/index.html') + + +@bp.get('/add') +@authorize("admin:comic:add", log=True) +def add(): + return render_template("admin/comic/add.html") + + +@bp.get("/data") +@authorize("admin:comic:index") +def index_data(): + # 获取请求参数 + comic_name = str_escape(request.args.get('comicName', type=str)) + user_id = request.args.get('userId', type=int) + author_name = request.args.get('authorName', type=str) + + filters = [] + if comic_name: + filters.append(Comic.name.contains(comic_name)) + if author_name: + filters.append(User.name.contains(author_name)) + if user_id: + filters.append(Comic.author_id == user_id) + + query = db.session.query( + Comic, + User + ).filter(*filters).outerjoin(User, User.id == Comic.author_id).layui_paginate() + + return table_api( + data=[{ + 'id': comic.id, + 'name': comic.name, + 'description': comic.description, + 'authorName': user.username, + 'coverImage': comic.cover_image, + 'status': comic.status, + 'releaseDate': date_format(comic.release_date), + 'createdAt': date_format(comic.created_at), + 'updatedAt': date_format(comic.updated_at), + } for comic, user in query.items], + count=query.total) + + +@bp.post('/') +@authorize("admin:comic:add") +def save(): + req_json = request.get_json(force=True) + print(req_json) + name = req_json.get('name') + if name is None: + return fail_api(msg="名称不能为空") + author_id = session.get("_user_id") + description = req_json.get('description') + cover_image = req_json.get('coverImage') + release_date = req_json.get('releaseDate') or None + if release_date is not None and release_date != '': + release_date = datetime.strptime(release_date, '%Y-%m-%d') + status = req_json.get('status') or '0' + comic = Comic(name=name, + author_id=author_id, + description=description, + cover_image=cover_image, + release_date=release_date, + status=status) + db.session.add(comic) + db.session.commit() + return success_api(msg="增加成功") + + +def date_format(date, format_str='%Y-%m-%d %H:%M:%S'): + return date.strftime(format_str) if date else None diff --git a/applications/view/system/index.py b/applications/view/system/index.py index bbd6b6a..984efdf 100644 --- a/applications/view/system/index.py +++ b/applications/view/system/index.py @@ -1,14 +1,18 @@ -from flask import Blueprint, render_template +from flask import Blueprint, render_template, redirect, url_for from flask_login import login_required, current_user bp = Blueprint('index', __name__, url_prefix='/') # 首页 -@bp.get('/') +@bp.get('/system') @login_required def index(): user = current_user return render_template('system/index.html', user=user) +@bp.get('/') +def comic_index(): + return redirect(url_for('comics.index')) + diff --git a/plugins/comic/__init__.json b/plugins/comic/__init__.json new file mode 100644 index 0000000..3e177c4 --- /dev/null +++ b/plugins/comic/__init__.json @@ -0,0 +1,5 @@ +{ + "plugin_name": "Comic Show", + "plugin_version": "1.0.0", + "plugin_description": "漫画前端展示" +} \ No newline at end of file diff --git a/plugins/comic/__init__.py b/plugins/comic/__init__.py new file mode 100644 index 0000000..c3f3614 --- /dev/null +++ b/plugins/comic/__init__.py @@ -0,0 +1,13 @@ +import os + +# 获取插件所在的目录(结尾没有分割符号) +from flask import Flask +from plugins.comic.index import bp_comic +dir_path = os.path.dirname(__file__).replace("\\", "/") +# 插件文件夹名称 +folder_name = dir_path[dir_path.rfind("/") + 1:] + + +def event_init(app: Flask): + """初始化完成时会调用这里""" + app.register_blueprint(bp_comic) diff --git a/plugins/comic/index.py b/plugins/comic/index.py new file mode 100644 index 0000000..c1a8652 --- /dev/null +++ b/plugins/comic/index.py @@ -0,0 +1,8 @@ +from flask import Blueprint, render_template + +bp_comic = Blueprint('comics', __name__, template_folder='templates', static_folder="static", url_prefix="/comics") + + +@bp_comic.get('/') +def index(): + return render_template("index.html") diff --git a/plugins/comic/templates/index.html b/plugins/comic/templates/index.html new file mode 100644 index 0000000..43c69af --- /dev/null +++ b/plugins/comic/templates/index.html @@ -0,0 +1,12 @@ + + +
+ +