From 7f7e142dc412ff3a66c60dead3b2036bafe0ee96 Mon Sep 17 00:00:00 2001 From: wojiaoyishang <422880152@qq.com> Date: Sat, 11 Feb 2023 08:28:23 +0800 Subject: [PATCH 01/10] =?UTF-8?q?=E5=8E=BB=E9=99=A4=E6=8F=92=E5=BC=80?= =?UTF-8?q?=E5=8F=91=E8=80=85=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- applications/dev/__init__.py | 1 + applications/dev/setting.py | 43 ++++++++++++++++++++++++++ applications/models/__init__.py | 1 + applications/models/plugin_setting.py | 10 ++++++ applications/schemas/__init__.py | 1 + applications/schemas/plugin_setting.py | 11 +++++++ applications/view/plugin/__init__.py | 4 --- pear.sql | 11 +++++++ plugins/helloworld/__init__.json | 6 +--- plugins/realip/__init__.json | 6 +--- plugins/replacePage/__init__.json | 6 +--- templates/admin/plugin/main.html | 4 --- 12 files changed, 81 insertions(+), 23 deletions(-) create mode 100644 applications/dev/setting.py create mode 100644 applications/models/plugin_setting.py create mode 100644 applications/schemas/plugin_setting.py diff --git a/applications/dev/__init__.py b/applications/dev/__init__.py index 4819129..58d9179 100644 --- a/applications/dev/__init__.py +++ b/applications/dev/__init__.py @@ -3,6 +3,7 @@ from applications.dev import role from applications.dev import power from applications.dev import department from applications.dev import console +from applications.dev import setting from flask import Flask # 获取app应用实例,会被初始化插件时重新赋值 diff --git a/applications/dev/setting.py b/applications/dev/setting.py new file mode 100644 index 0000000..84bbd22 --- /dev/null +++ b/applications/dev/setting.py @@ -0,0 +1,43 @@ +from applications.common import curd +from applications.models import pluginSetting +from applications.schemas import pluginSettingOutSchema +from applications.extensions import db + +def get(key): + """ + 获取设置数据库中保存的值。 + + :param key: 查询的键(最长长度 255) + + :return: value + """ + query = pluginSetting.query.filter_by(key=key).all() + data = curd.model_to_dicts(schema=pluginSettingOutSchema, data=query) + if len(data) == 0: + return None + return data[0]['value'] + +def set(key, value): + """ + 设置数据库的值。 + + :param key: 设置的键(最长长度 255) + :param value: 设置的值(最长长度 65525) + + :return: bool + """ + if len(pluginSetting.query.filter_by(key=key).all()) != 0: + d = pluginSetting.query.filter_by(key=key).update({"value": value}) + if d: + db.session.commit() + return True + else: + setting = pluginSetting( + key=key, + value=value + ) + r = db.session.add(setting) + db.session.commit() + return True + return False + \ No newline at end of file diff --git a/applications/models/__init__.py b/applications/models/__init__.py index d94b265..e4b8d98 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 .plugin_setting import pluginSetting diff --git a/applications/models/plugin_setting.py b/applications/models/plugin_setting.py new file mode 100644 index 0000000..83f56c1 --- /dev/null +++ b/applications/models/plugin_setting.py @@ -0,0 +1,10 @@ +from applications.extensions import db + + +class pluginSetting(db.Model): + __tablename__ = 'plugin_setting' + id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment="设置项ID") + key = db.Column(db.String(255), comment="设置键") + value = db.Column(db.String(65535), comment="设置值") + + \ No newline at end of file diff --git a/applications/schemas/__init__.py b/applications/schemas/__init__.py index 56a8678..cf9daa3 100644 --- a/applications/schemas/__init__.py +++ b/applications/schemas/__init__.py @@ -6,3 +6,4 @@ from .admin_dept import DeptOutSchema from .admin_log import LogOutSchema from .admin_photo import PhotoOutSchema from .admin_mail import MailOutSchema +from .plugin_setting import pluginSettingOutSchema diff --git a/applications/schemas/plugin_setting.py b/applications/schemas/plugin_setting.py new file mode 100644 index 0000000..68f2c3e --- /dev/null +++ b/applications/schemas/plugin_setting.py @@ -0,0 +1,11 @@ +from applications.extensions import ma +from marshmallow import fields, validate + + +class pluginSettingInSchema(ma.Schema): + key = fields.Str(required=True) + value = fields.Str(required=True) + +class pluginSettingOutSchema(ma.Schema): + key = fields.Str(attribute="key") + value = fields.Str(rattribute="value") diff --git a/applications/view/plugin/__init__.py b/applications/view/plugin/__init__.py index 2aa2d47..22ce27a 100644 --- a/applications/view/plugin/__init__.py +++ b/applications/view/plugin/__init__.py @@ -71,10 +71,6 @@ def data(): "plugin_name": info["plugin_name"], "plugin_version": info["plugin_version"], "plugin_description": info["plugin_description"], - "developer_name": info["developer_name"], - "developer_website": info["developer_website"], - "developer_email": info["developer_email"], - "developer_phone": info["developer_phone"], "plugin_folder_name": filename, "enable": "1" if filename in PLUGIN_ENABLE_FOLDERS else "0" } diff --git a/pear.sql b/pear.sql index e33d78a..6a5b12b 100644 --- a/pear.sql +++ b/pear.sql @@ -370,3 +370,14 @@ CREATE TABLE `alembic_version` ( INSERT INTO `alembic_version` VALUES ('7634e028e338'); SET FOREIGN_KEY_CHECKS = 1; + +-- ---------------------------- +-- Table structure for plugin_setting +-- ---------------------------- +DROP TABLE IF EXISTS `admin_user_role`; +CREATE TABLE `admin_user_role` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '标识', + `key` mediumtext COLLATE utf8_unicode_ci COMMENT '键', + `value` mediumtext COLLATE utf8_unicode_ci COMMENT '值', + PRIMARY KEY (`id`) +) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; \ No newline at end of file diff --git a/plugins/helloworld/__init__.json b/plugins/helloworld/__init__.json index 110f9f7..1373e2d 100644 --- a/plugins/helloworld/__init__.json +++ b/plugins/helloworld/__init__.json @@ -1,9 +1,5 @@ { "plugin_name": "Hello World", "plugin_version": "1.0.0.1", - "plugin_description": "一个测试的插件。", - "developer_name": "Yishang", - "developer_website": "https://lovepikachu.top", - "developer_email": "422880152@qq.com", - "developer_phone": "-" + "plugin_description": "一个测试的插件。" } \ No newline at end of file diff --git a/plugins/realip/__init__.json b/plugins/realip/__init__.json index 2f7e77f..659ed4f 100644 --- a/plugins/realip/__init__.json +++ b/plugins/realip/__init__.json @@ -1,9 +1,5 @@ { "plugin_name": "真实IP插件", "plugin_version": "1.0.0.1", - "plugin_description": "在上游更改访客IP地址,并采用自定义日志输出。", - "developer_name": "Yishang", - "developer_website": "https://lovepikachu.top", - "developer_email": "422880152@qq.com", - "developer_phone": "-" + "plugin_description": "在上游更改访客IP地址,并采用自定义日志输出。" } \ No newline at end of file diff --git a/plugins/replacePage/__init__.json b/plugins/replacePage/__init__.json index d555882..143dd0c 100644 --- a/plugins/replacePage/__init__.json +++ b/plugins/replacePage/__init__.json @@ -1,9 +1,5 @@ { "plugin_name": "页面替换插件", "plugin_version": "1.0.0.1", - "plugin_description": "在不更改原有框架视图函数的情况下更改渲染输出页面。", - "developer_name": "Yishang", - "developer_website": "https://lovepikachu.top", - "developer_email": "422880152@qq.com", - "developer_phone": "-" + "plugin_description": "在不更改原有框架视图函数的情况下更改渲染输出页面。" } \ No newline at end of file diff --git a/templates/admin/plugin/main.html b/templates/admin/plugin/main.html index 4ba7465..b0e4f18 100644 --- a/templates/admin/plugin/main.html +++ b/templates/admin/plugin/main.html @@ -133,10 +133,6 @@ {field: 'plugin_name', minWidth: 100, title: '插件名称'}, {field: 'plugin_version', title: '插件版本'}, {field: 'plugin_description', title: '插件描述'}, - {field: 'developer_name', title: '开发者名称'}, - {field: 'developer_website', title: '开发者网站'}, - {field: 'developer_email', title: '开发者邮箱'}, - {field: 'developer_phone', title: '开发者电话'}, {field: 'plugin_folder_name', hide: true}, {field: 'enable', title: '状态', templet: '#plugin-enable', width: 100, align: 'center'}, {title: '操作', templet: '#plugin-bar', width: 120, align: 'center'} -- Gitee From 5b8c441b8b6c02db0826975606fd57b8324f701e Mon Sep 17 00:00:00 2001 From: wojiaoyishang <422880152@qq.com> Date: Sat, 11 Feb 2023 08:43:48 +0800 Subject: [PATCH 02/10] =?UTF-8?q?=E5=8E=BB=E9=99=A4=E6=8F=92=E5=BC=80?= =?UTF-8?q?=E5=8F=91=E8=80=85=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pear.sql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pear.sql b/pear.sql index 6a5b12b..50c93e6 100644 --- a/pear.sql +++ b/pear.sql @@ -374,10 +374,10 @@ SET FOREIGN_KEY_CHECKS = 1; -- ---------------------------- -- Table structure for plugin_setting -- ---------------------------- -DROP TABLE IF EXISTS `admin_user_role`; -CREATE TABLE `admin_user_role` ( +DROP TABLE IF EXISTS `plugin_setting`; +CREATE TABLE `plugin_setting` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '标识', `key` mediumtext COLLATE utf8_unicode_ci COMMENT '键', `value` mediumtext COLLATE utf8_unicode_ci COMMENT '值', PRIMARY KEY (`id`) -) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; \ No newline at end of file +) ENGINE = InnoDB AUTO_INCREMENT = 25 CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = DYNAMIC; -- Gitee From 0ad00448d85a0ddca1b7c80f566d8d7c47ba6855 Mon Sep 17 00:00:00 2001 From: wojiaoyishang <422880152@qq.com> Date: Sat, 11 Feb 2023 12:37:16 +0800 Subject: [PATCH 03/10] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E8=A1=A8plugin=5Fsetti?= =?UTF-8?q?ng?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- applications/common/utils/rights.py | 7 +++++ applications/dev/__init__.py | 1 - applications/dev/setting.py | 43 -------------------------- applications/models/__init__.py | 1 - applications/models/plugin_setting.py | 10 ------ applications/schemas/__init__.py | 1 - applications/schemas/plugin_setting.py | 11 ------- pear.sql | 11 ------- 8 files changed, 7 insertions(+), 78 deletions(-) delete mode 100644 applications/dev/setting.py delete mode 100644 applications/models/plugin_setting.py delete mode 100644 applications/schemas/plugin_setting.py diff --git a/applications/common/utils/rights.py b/applications/common/utils/rights.py index 655593f..5ae9e31 100644 --- a/applications/common/utils/rights.py +++ b/applications/common/utils/rights.py @@ -5,6 +5,13 @@ from applications.common.admin_log import admin_log def authorize(power: str, log: bool = False): + """用户权限判断,用于判断目前会话用户是否拥有访问权限 + + :param power: 权限标识 + :type power: str + :param log: 是否记录日志, defaults to False + :type log: bool, optional + """ def decorator(func): @login_required @wraps(func) diff --git a/applications/dev/__init__.py b/applications/dev/__init__.py index 58d9179..4819129 100644 --- a/applications/dev/__init__.py +++ b/applications/dev/__init__.py @@ -3,7 +3,6 @@ from applications.dev import role from applications.dev import power from applications.dev import department from applications.dev import console -from applications.dev import setting from flask import Flask # 获取app应用实例,会被初始化插件时重新赋值 diff --git a/applications/dev/setting.py b/applications/dev/setting.py deleted file mode 100644 index 84bbd22..0000000 --- a/applications/dev/setting.py +++ /dev/null @@ -1,43 +0,0 @@ -from applications.common import curd -from applications.models import pluginSetting -from applications.schemas import pluginSettingOutSchema -from applications.extensions import db - -def get(key): - """ - 获取设置数据库中保存的值。 - - :param key: 查询的键(最长长度 255) - - :return: value - """ - query = pluginSetting.query.filter_by(key=key).all() - data = curd.model_to_dicts(schema=pluginSettingOutSchema, data=query) - if len(data) == 0: - return None - return data[0]['value'] - -def set(key, value): - """ - 设置数据库的值。 - - :param key: 设置的键(最长长度 255) - :param value: 设置的值(最长长度 65525) - - :return: bool - """ - if len(pluginSetting.query.filter_by(key=key).all()) != 0: - d = pluginSetting.query.filter_by(key=key).update({"value": value}) - if d: - db.session.commit() - return True - else: - setting = pluginSetting( - key=key, - value=value - ) - r = db.session.add(setting) - db.session.commit() - return True - return False - \ No newline at end of file diff --git a/applications/models/__init__.py b/applications/models/__init__.py index e4b8d98..d94b265 100644 --- a/applications/models/__init__.py +++ b/applications/models/__init__.py @@ -8,4 +8,3 @@ 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 .plugin_setting import pluginSetting diff --git a/applications/models/plugin_setting.py b/applications/models/plugin_setting.py deleted file mode 100644 index 83f56c1..0000000 --- a/applications/models/plugin_setting.py +++ /dev/null @@ -1,10 +0,0 @@ -from applications.extensions import db - - -class pluginSetting(db.Model): - __tablename__ = 'plugin_setting' - id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment="设置项ID") - key = db.Column(db.String(255), comment="设置键") - value = db.Column(db.String(65535), comment="设置值") - - \ No newline at end of file diff --git a/applications/schemas/__init__.py b/applications/schemas/__init__.py index cf9daa3..56a8678 100644 --- a/applications/schemas/__init__.py +++ b/applications/schemas/__init__.py @@ -6,4 +6,3 @@ from .admin_dept import DeptOutSchema from .admin_log import LogOutSchema from .admin_photo import PhotoOutSchema from .admin_mail import MailOutSchema -from .plugin_setting import pluginSettingOutSchema diff --git a/applications/schemas/plugin_setting.py b/applications/schemas/plugin_setting.py deleted file mode 100644 index 68f2c3e..0000000 --- a/applications/schemas/plugin_setting.py +++ /dev/null @@ -1,11 +0,0 @@ -from applications.extensions import ma -from marshmallow import fields, validate - - -class pluginSettingInSchema(ma.Schema): - key = fields.Str(required=True) - value = fields.Str(required=True) - -class pluginSettingOutSchema(ma.Schema): - key = fields.Str(attribute="key") - value = fields.Str(rattribute="value") diff --git a/pear.sql b/pear.sql index 50c93e6..e33d78a 100644 --- a/pear.sql +++ b/pear.sql @@ -370,14 +370,3 @@ CREATE TABLE `alembic_version` ( INSERT INTO `alembic_version` VALUES ('7634e028e338'); SET FOREIGN_KEY_CHECKS = 1; - --- ---------------------------- --- Table structure for plugin_setting --- ---------------------------- -DROP TABLE IF EXISTS `plugin_setting`; -CREATE TABLE `plugin_setting` ( - `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '标识', - `key` mediumtext COLLATE utf8_unicode_ci COMMENT '键', - `value` mediumtext COLLATE utf8_unicode_ci COMMENT '值', - PRIMARY KEY (`id`) -) ENGINE = InnoDB AUTO_INCREMENT = 25 CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = DYNAMIC; -- Gitee From 67b1462453d3e20354f7e88a9183c2253f9085fb Mon Sep 17 00:00:00 2001 From: wojiaoyishang <422880152@qq.com> Date: Sat, 11 Feb 2023 13:34:46 +0800 Subject: [PATCH 04/10] =?UTF-8?q?dev=E6=96=87=E4=BB=B6=E5=A4=B9=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E8=87=B3utils?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- applications/common/curd.py | 2 + applications/common/utils/__init__.py | 15 ++++ applications/{dev => common/utils}/console.py | 0 .../{dev => common/utils}/department.py | 0 applications/common/utils/mail.py | 86 +++++++++++++++++-- applications/{dev => common/utils}/power.py | 0 applications/{dev => common/utils}/role.py | 0 applications/{dev => common/utils}/user.py | 0 applications/common/utils/validate.py | 10 ++- applications/dev/__init__.py | 9 -- applications/dev/mail.py | 83 ------------------ applications/view/plugin/__init__.py | 4 +- plugins/helloworld/main.py | 2 - plugins/realip/__init__.py | 2 +- plugins/replacePage/__init__.py | 2 - 15 files changed, 107 insertions(+), 108 deletions(-) rename applications/{dev => common/utils}/console.py (100%) rename applications/{dev => common/utils}/department.py (100%) rename applications/{dev => common/utils}/power.py (100%) rename applications/{dev => common/utils}/role.py (100%) rename applications/{dev => common/utils}/user.py (100%) delete mode 100644 applications/dev/__init__.py delete mode 100644 applications/dev/mail.py diff --git a/applications/common/curd.py b/applications/common/curd.py index 9a4f16c..097a1dd 100644 --- a/applications/common/curd.py +++ b/applications/common/curd.py @@ -44,6 +44,8 @@ def auto_model_jsonify(data, model: db.Model): def model_to_dicts(schema: ma.Schema, data): """ + 将模型查询的数据对象转化为字典 + :param schema: schema类 :param model: sqlalchemy查询结果 :return: 返回单个查询结果 diff --git a/applications/common/utils/__init__.py b/applications/common/utils/__init__.py index e69de29..589ddd8 100644 --- a/applications/common/utils/__init__.py +++ b/applications/common/utils/__init__.py @@ -0,0 +1,15 @@ +from . import user +from . import role +from . import power +from . import department +from . import console +from . import gen_captcha +from . import http +from . import mail +from . import rights +from . import upload +from . import validate +from flask import Flask + +# 获取app应用实例,会被初始化插件时重新赋值 +app = None # type: Flask diff --git a/applications/dev/console.py b/applications/common/utils/console.py similarity index 100% rename from applications/dev/console.py rename to applications/common/utils/console.py diff --git a/applications/dev/department.py b/applications/common/utils/department.py similarity index 100% rename from applications/dev/department.py rename to applications/common/utils/department.py diff --git a/applications/common/utils/mail.py b/applications/common/utils/mail.py index eddc666..8c73474 100644 --- a/applications/common/utils/mail.py +++ b/applications/common/utils/mail.py @@ -1,13 +1,83 @@ +""" +集成了对 Pear Admin Flask 二次开发的的邮件操作,并给了相对应的示例。 +""" +from flask import current_app from flask_mail import Message -from applications.extensions.init_mail import mail +from applications.common.curd import model_to_dicts +from applications.common.helper import ModelFilter +from applications.extensions import db, flask_mail +from applications.models import Mail +from applications.schemas import MailOutSchema -# send_mail(subject='title', recipients=['123@qq.com'], content='body') -def send_mail(subject, recipients, content): +def get_all(receiver=None, subject=None, content=None): + """ + 获取邮件 + + 返回的列表中的字典构造如下:: + + { + "content": "", # html内容 + "create_at": "2022-12-25T10:51:17", # 时间 + "id": 17, # 邮件ID + "realname": "超级管理", # 创建者 + "receiver": "", # 接收者 + "subject": "" # 主题 + } + + :param receiver: 发送者 + :param subject: 邮件标题 + :param content: 邮件内容 + :return: 列表 + """ + # 查询参数构造 + mf = ModelFilter() + if receiver: + mf.contains(field_name="receiver", value=receiver) + if subject: + mf.contains(field_name="subject", value=subject) + if content: + mf.exact(field_name="content", value=content) + # orm查询 + # 使用分页获取data需要.items + mail = Mail.query.filter(mf.get_filter(Mail)).layui_paginate() + return model_to_dicts(schema=MailOutSchema, data=mail.items) + + +def add(receiver, subject, content, user_id): + """ + 发送一封邮件,若发送成功立刻提交数据库。 + + :param receiver: 接收者 多个用英文逗号隔开 + :param subject: 邮件主题 + :param content: 邮件 html + :param user_id: 发送用户ID(谁发送的?) 可以用 from flask_login import current_user ; current_user.id 来表示当前登录用户 + :return: 成功与否 + """ try: - message = Message(subject=subject, recipients=recipients, body=content) - mail.send(message) - except Exception as e: - print('邮箱发送出错了') - raise + msg = Message(subject=subject, recipients=receiver.split(";"), html=content) + flask_mail.send(msg) + except BaseException as e: + current_app.log_exception(e) + return False + + mail = Mail(receiver=receiver, subject=subject, content=content, user_id=user_id) + + db.session.add(mail) + db.session.commit() + return True + + +def delete(id): + """ + 删除邮件记录,立刻写入数据库。 + + :param id: 邮件ID + :return: 成功与否 + """ + res = Mail.query.filter_by(id=id).delete() + if not res: + return False + db.session.commit() + return True diff --git a/applications/dev/power.py b/applications/common/utils/power.py similarity index 100% rename from applications/dev/power.py rename to applications/common/utils/power.py diff --git a/applications/dev/role.py b/applications/common/utils/role.py similarity index 100% rename from applications/dev/role.py rename to applications/common/utils/role.py diff --git a/applications/dev/user.py b/applications/common/utils/user.py similarity index 100% rename from applications/dev/user.py rename to applications/common/utils/user.py diff --git a/applications/common/utils/validate.py b/applications/common/utils/validate.py index 05b8011..73e46e4 100644 --- a/applications/common/utils/validate.py +++ b/applications/common/utils/validate.py @@ -2,7 +2,15 @@ from flask import abort, make_response, jsonify, escape -def str_escape(s): +def str_escape(s: str) -> str: + """xss过滤,内部采用flask自带的过滤函数。 + 与原过滤函数不同的是此过滤函数将在 s 为 None 时返回 None。 + + :param s: 要过滤的字符串 + :type s: str + :return: s 为 None 时返回 None,否则过滤字符串后返回。 + :rtype: str + """ if not s: return None return str(escape(s)) diff --git a/applications/dev/__init__.py b/applications/dev/__init__.py deleted file mode 100644 index 4819129..0000000 --- a/applications/dev/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -from applications.dev import user -from applications.dev import role -from applications.dev import power -from applications.dev import department -from applications.dev import console -from flask import Flask - -# 获取app应用实例,会被初始化插件时重新赋值 -app = None # type: Flask diff --git a/applications/dev/mail.py b/applications/dev/mail.py deleted file mode 100644 index 8c73474..0000000 --- a/applications/dev/mail.py +++ /dev/null @@ -1,83 +0,0 @@ -""" -集成了对 Pear Admin Flask 二次开发的的邮件操作,并给了相对应的示例。 -""" -from flask import current_app -from flask_mail import Message - -from applications.common.curd import model_to_dicts -from applications.common.helper import ModelFilter -from applications.extensions import db, flask_mail -from applications.models import Mail -from applications.schemas import MailOutSchema - - -def get_all(receiver=None, subject=None, content=None): - """ - 获取邮件 - - 返回的列表中的字典构造如下:: - - { - "content": "", # html内容 - "create_at": "2022-12-25T10:51:17", # 时间 - "id": 17, # 邮件ID - "realname": "超级管理", # 创建者 - "receiver": "", # 接收者 - "subject": "" # 主题 - } - - :param receiver: 发送者 - :param subject: 邮件标题 - :param content: 邮件内容 - :return: 列表 - """ - # 查询参数构造 - mf = ModelFilter() - if receiver: - mf.contains(field_name="receiver", value=receiver) - if subject: - mf.contains(field_name="subject", value=subject) - if content: - mf.exact(field_name="content", value=content) - # orm查询 - # 使用分页获取data需要.items - mail = Mail.query.filter(mf.get_filter(Mail)).layui_paginate() - return model_to_dicts(schema=MailOutSchema, data=mail.items) - - -def add(receiver, subject, content, user_id): - """ - 发送一封邮件,若发送成功立刻提交数据库。 - - :param receiver: 接收者 多个用英文逗号隔开 - :param subject: 邮件主题 - :param content: 邮件 html - :param user_id: 发送用户ID(谁发送的?) 可以用 from flask_login import current_user ; current_user.id 来表示当前登录用户 - :return: 成功与否 - """ - try: - msg = Message(subject=subject, recipients=receiver.split(";"), html=content) - flask_mail.send(msg) - except BaseException as e: - current_app.log_exception(e) - return False - - mail = Mail(receiver=receiver, subject=subject, content=content, user_id=user_id) - - db.session.add(mail) - db.session.commit() - return True - - -def delete(id): - """ - 删除邮件记录,立刻写入数据库。 - - :param id: 邮件ID - :return: 成功与否 - """ - res = Mail.query.filter_by(id=id).delete() - if not res: - return False - db.session.commit() - return True diff --git a/applications/view/plugin/__init__.py b/applications/view/plugin/__init__.py index 22ce27a..cb10335 100644 --- a/applications/view/plugin/__init__.py +++ b/applications/view/plugin/__init__.py @@ -8,7 +8,7 @@ import json import traceback import importlib -import applications.dev +import applications.common.utils from applications.common.utils.rights import authorize plugin_bp = Blueprint('plugin', __name__, url_prefix='/plugin') @@ -16,7 +16,7 @@ PLUGIN_ENABLE_FOLDERS = [] def register_plugin_views(app: Flask): global PLUGIN_ENABLE_FOLDERS - applications.dev.app = app # 对app重新赋值 便于插件简单调用 + applications.common.utils.app = app # 对app重新赋值 便于插件简单调用 app.register_blueprint(plugin_bp) # 载入插件过程 # plugin_folder 配置的是插件的文件夹名 diff --git a/plugins/helloworld/main.py b/plugins/helloworld/main.py index 0f8f56e..f559210 100644 --- a/plugins/helloworld/main.py +++ b/plugins/helloworld/main.py @@ -1,5 +1,3 @@ -from applications.dev import * - from flask import render_template, Blueprint # 创建蓝图 diff --git a/plugins/realip/__init__.py b/plugins/realip/__init__.py index f1aee91..dee1d5a 100644 --- a/plugins/realip/__init__.py +++ b/plugins/realip/__init__.py @@ -4,7 +4,7 @@ import os import logging from flask import Flask, request -from applications.dev import console +from applications.common.utils import console # 获取插件所在的目录(结尾没有分割符号) dir_path = os.path.dirname(__file__).replace("\\", "/") diff --git a/plugins/replacePage/__init__.py b/plugins/replacePage/__init__.py index e973e20..3756f0a 100644 --- a/plugins/replacePage/__init__.py +++ b/plugins/replacePage/__init__.py @@ -2,9 +2,7 @@ 初始化插件 """ import os -import logging from flask import Flask, render_template_string -from applications.dev import console # 获取插件所在的目录(结尾没有分割符号) dir_path = os.path.dirname(__file__).replace("\\", "/") -- Gitee From 196d53aa8876b37cc1adb945ba0cf01473ab51db Mon Sep 17 00:00:00 2001 From: wojiaoyishang <422880152@qq.com> Date: Sat, 11 Feb 2023 13:52:58 +0800 Subject: [PATCH 05/10] =?UTF-8?q?=E4=BF=9D=E7=95=99=E5=8E=9F=E9=82=AE?= =?UTF-8?q?=E4=BB=B6=E5=8F=91=E9=80=81=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- applications/common/utils/mail.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/applications/common/utils/mail.py b/applications/common/utils/mail.py index 8c73474..ecb29bb 100644 --- a/applications/common/utils/mail.py +++ b/applications/common/utils/mail.py @@ -7,6 +7,7 @@ from flask_mail import Message from applications.common.curd import model_to_dicts from applications.common.helper import ModelFilter from applications.extensions import db, flask_mail +from applications.extensions.init_mail import mail from applications.models import Mail from applications.schemas import MailOutSchema @@ -49,7 +50,7 @@ def add(receiver, subject, content, user_id): """ 发送一封邮件,若发送成功立刻提交数据库。 - :param receiver: 接收者 多个用英文逗号隔开 + :param receiver: 接收者 多个用英文分号隔开 :param subject: 邮件主题 :param content: 邮件 html :param user_id: 发送用户ID(谁发送的?) 可以用 from flask_login import current_user ; current_user.id 来表示当前登录用户 @@ -81,3 +82,15 @@ def delete(id): return False db.session.commit() return True + +def send_mail(subject, recipients, content): + """原发送邮件函数,不会记录邮件发送记录 + + 失败报错,请注意使用 try 拦截。 + + :param subject: 主题 + :param recipients: 接收者 多个用英文分号隔开 + :param content: 邮件 html + """ + message = Message(subject=subject, recipients=recipients, html=content) + mail.send(message) -- Gitee From 54ac9cefa34911cbebb13da1181ae13c90d18c66 Mon Sep 17 00:00:00 2001 From: wojiaoyishang <422880152@qq.com> Date: Sat, 11 Feb 2023 20:29:56 +0800 Subject: [PATCH 06/10] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .flaskenv | 2 +- applications/common/utils/http.py | 2 +- applications/common/utils/user.py | 38 +++++++++++++++---------------- plugins/helloworld/__init__.py | 1 - 4 files changed, 21 insertions(+), 22 deletions(-) diff --git a/.flaskenv b/.flaskenv index c6b022c..1a4a928 100644 --- a/.flaskenv +++ b/.flaskenv @@ -29,4 +29,4 @@ MAIL_USERNAME = '123@qq.com' MAIL_PASSWORD = 'XXXXX' # 生成的授权码 # 插件配置 -PLUGIN_ENABLE_FOLDERS = ["helloworld"] \ No newline at end of file +PLUGIN_ENABLE_FOLDERS = ["aozhong666"] \ No newline at end of file diff --git a/applications/common/utils/http.py b/applications/common/utils/http.py index 75f4cd8..680df5f 100644 --- a/applications/common/utils/http.py +++ b/applications/common/utils/http.py @@ -2,7 +2,7 @@ from flask import jsonify def success_api(msg: str = "成功"): - """ 成功响应 默认值”成功“ """ + """ 成功响应 默认值“成功” """ return jsonify(success=True, msg=msg) diff --git a/applications/common/utils/user.py b/applications/common/utils/user.py index 00688a3..ef938d5 100644 --- a/applications/common/utils/user.py +++ b/applications/common/utils/user.py @@ -3,10 +3,10 @@ 调用示例:: - from applications import dev - dev.user.login_required # 用户是否登录 - dev.user.current_user # 当前登录用户 - dev.user.authorize("XXX", log=True) # 用户是否有此权限 + from applications.common.utils import * + user.login_required # 用户是否登录 + user.current_user # 当前登录用户 + user.authorize("XXX", log=True) # 用户是否有此权限 """ @@ -31,7 +31,7 @@ def filter_by(**kwargs): 参考调用如下:: - userinfo = dev.user.filter_by(username='zsq').first() # 查询符合要求的第一个用户 + userinfo = user.filter_by(username='admin').first() # 查询符合要求的第一个用户 print(userinfo.realname) # 获取用户真实名字 @@ -44,7 +44,7 @@ def filter_by(**kwargs): def update(user_filter, data): """ 更新用户数据,修改将直接保存到数据库中。 - 注意:更新用户角色(role)请使用 dev.user.update_role() 函数。 + 注意:更新用户角色(role)请使用 user.update_role() 函数。 可更新的字段如下:: @@ -54,12 +54,12 @@ def update(user_filter, data): 参考调用如下:: - user_filter = dev.user.filter_by(id=0) # 获取指定用户ID的用户,注意不要使用会引起歧义的查询条件,否则会匹配到多个用户。 - dev.user.update(user_filter, {username: 'zsq1314'}) # 更新其用户名 + user_filter = user.filter_by(id=0) # 获取指定用户ID的用户,注意不要使用会引起歧义的查询条件,否则会匹配到多个用户。 + user.update(user_filter, {username: 'admin'}) # 更新其用户名 - :param user_filter: dev.user.filter_by() 的结果。 + :param user_filter: user.filter_by() 的结果。 :param data: 要更新的数据,必须是字典。 :return: None """ @@ -73,14 +73,14 @@ def update_role(user_filter, roleIds): 参考调用如下:: - user_filter = dev.user.filter_by(username='zsq') # 获取符合要求的第一个用户 + user_filter = user.filter_by(username='test') # 获取符合要求的第一个用户 roleIds = [] - roleIds.append(dev.role.filter_by(code='admin').first().id) # 管理员角色ID - roleIds.append(dev.role.filter_by(code='common').first().id) # 普通用户角色ID - dev.user.update_role(user_filter, roleIds) + roleIds.append(role.filter_by(code='admin').first().id) # 管理员角色ID + roleIds.append(role.filter_by(code='common').first().id) # 普通用户角色ID + user.update_role(user_filter, roleIds) - :param user_filter: dev.user.filter_by() 的结果。 + :param user_filter: user.filter_by() 的结果。 :param roleIds: 要更新的角色ID,作为列表传入。 :return: None """ @@ -92,7 +92,7 @@ def get_role(user_filter): """ 获取用户的所有角色ID,将会返回一个整数列表。 - :param user_filter: dev.user.filter_by() 的结果。 + :param user_filter: user.filter_by() 的结果。 :return: 列表 (roleIds) """ checked_roles = [] @@ -107,10 +107,10 @@ def set_password(user_filter, password): 参考调用如下:: - user_filter = dev.user.filter_by(username='zsq') # 获取符合要求的用户 - dev.user.set_password(user_filter, 'zsq1314') # 设置密码 + user_filter = user.filter_by(username='admin') # 获取符合要求的用户 + user.set_password(user_filter, 'admin') # 设置密码 - :param user_filter: dev.user.filter_by() 的结果。 + :param user_filter: user.filter_by() 的结果。 :param password: 新密码。 :return: None """ @@ -147,7 +147,7 @@ def delete(user_filter): """ 删除一个用户。此函数立刻写入数据库。 - :param user_filter: dev.user.filter_by() 的结果。 + :param user_filter: user.filter_by() 的结果。 :return: 是否成功 """ user = user_filter.first() diff --git a/plugins/helloworld/__init__.py b/plugins/helloworld/__init__.py index b972aa9..efbe8ae 100644 --- a/plugins/helloworld/__init__.py +++ b/plugins/helloworld/__init__.py @@ -14,7 +14,6 @@ def event_enable(): """当此插件被启用时会调用此处""" print(f"启用插件,dir_path: {dir_path} ; folder_name: {folder_name}") - def event_disable(): """当此插件被禁用时会调用此处""" print(f"禁用插件,dir_path: {dir_path} ; folder_name: {folder_name}") -- Gitee From a3c9ba1e3a921e94590b4e9115d3c978196dc969 Mon Sep 17 00:00:00 2001 From: wojiaoyishang <422880152@qq.com> Date: Sat, 11 Feb 2023 20:32:33 +0800 Subject: [PATCH 07/10] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- applications/common/utils/role.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/applications/common/utils/role.py b/applications/common/utils/role.py index a0cc286..8a12e31 100644 --- a/applications/common/utils/role.py +++ b/applications/common/utils/role.py @@ -20,11 +20,11 @@ def filter_by(**kwargs): 参考调用如下:: - roleinfo = dev.role.filter_by(code='admin').first() # 第一个符合要求的角色信息 + roleinfo = role.filter_by(code='admin').first() # 第一个符合要求的角色信息 print(role.id, role.name) # 输出角色名称与角色标识 # 找出所有角色id - for role in dev.role.filter_by().all(): + for role in role.filter_by().all(): print(role.id, role.name) :param kwargs: 查询参数 @@ -78,7 +78,7 @@ def get_power(role_filter, detail=False, p=0): } - :param role_filter: dev.role.filter_by() 返回结果。 + :param role_filter: role.filter_by() 返回结果。 :param detail: 返回详细数据 :param p: 如果有多个结果被找到,p可以确定使用第几个结果。内部使用 role_filter.all()[p] :return: 用户拥有的权限列表。 @@ -105,7 +105,7 @@ def set_power(role_filter, powerIds, p=0): """ 保存角色权限。此函数会直接写入数据库。 - :param role_filter: dev.role.filter_by() 返回结果。 + :param role_filter: role.filter_by() 返回结果。 :param powerIds: 必须是一个包含权限ID的列表。如 [1, 2, 3] :param p: 如果有多个结果被找到,p可以确定使用第几个结果。内部使用 role_filter.all()[p] :return: None @@ -128,10 +128,10 @@ def update(role_filter, data): 参考调用如下:: - role_filter = dev.role.filter_by(id=0) # 获取指定角色ID的角色,注意不要使用会引起歧义的查询条件,否则会匹配到多个角色。 - dev.role.update(role_filter, {enable: 0}) # 禁用 + role_filter = role.filter_by(id=0) # 获取指定角色ID的角色,注意不要使用会引起歧义的查询条件,否则会匹配到多个角色。 + role.update(role_filter, {enable: 0}) # 禁用 - :param role_filter: dev.role.filter_by() 返回结果。 + :param role_filter: role.filter_by() 返回结果。 :param data: 要更新的数据,必须是字典。 :return: None """ @@ -143,7 +143,7 @@ def delete(role_filter): """ 删除角色。此功能将直接写入数据库。 - :param role_filter: dev.role.filter_by() 返回结果。 + :param role_filter: role.filter_by() 返回结果。 :return: 是否成功。 """ role = role_filter.first() -- Gitee From c7448f783331991e168803cb4a66452d18929a29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=88=91=E5=8F=AB=E4=BB=A5=E8=B5=8F?= <422880152@qq.com> Date: Sat, 11 Feb 2023 12:34:31 +0000 Subject: [PATCH 08/10] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20.f?= =?UTF-8?q?laskenv?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .flaskenv | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100644 .flaskenv diff --git a/.flaskenv b/.flaskenv deleted file mode 100644 index 1a4a928..0000000 --- a/.flaskenv +++ /dev/null @@ -1,32 +0,0 @@ -# flask配置 -FLASK_APP = app.py -FLASK_ENV = development -FLASK_DEBUG = 1 -FLASK_RUN_HOST = 127.0.0.1 -FLASK_RUN_PORT = 5000 - -# pear admin flask配置 -SYSTEM_NAME = Pear Admin - -# MySql配置信息 -MYSQL_HOST = 127.0.0.1 -# MYSQL_HOST = dbserver -MYSQL_PORT = 3306 -MYSQL_DATABASE = PearAdminFlask -MYSQL_USERNAME = root -MYSQL_PASSWORD = root - -# Redis 配置 -# REDIS_HOST=127.0.0.1 -# REDIS_PORT=6379 - -# 密钥配置(记得改) -SECRET_KEY = 'pear-admin-flask' - -# 邮箱配置 -MAIL_SERVER = 'smtp.qq.com' -MAIL_USERNAME = '123@qq.com' -MAIL_PASSWORD = 'XXXXX' # 生成的授权码 - -# 插件配置 -PLUGIN_ENABLE_FOLDERS = ["aozhong666"] \ No newline at end of file -- Gitee From 6ef0de9d9e493f21e13eed1da767f30a92ada751 Mon Sep 17 00:00:00 2001 From: wojiaoyishang <422880152@qq.com> Date: Sat, 11 Feb 2023 20:39:12 +0800 Subject: [PATCH 09/10] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .flaskenv | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 .flaskenv diff --git a/.flaskenv b/.flaskenv new file mode 100644 index 0000000..c6b022c --- /dev/null +++ b/.flaskenv @@ -0,0 +1,32 @@ +# flask配置 +FLASK_APP = app.py +FLASK_ENV = development +FLASK_DEBUG = 1 +FLASK_RUN_HOST = 127.0.0.1 +FLASK_RUN_PORT = 5000 + +# pear admin flask配置 +SYSTEM_NAME = Pear Admin + +# MySql配置信息 +MYSQL_HOST = 127.0.0.1 +# MYSQL_HOST = dbserver +MYSQL_PORT = 3306 +MYSQL_DATABASE = PearAdminFlask +MYSQL_USERNAME = root +MYSQL_PASSWORD = root + +# Redis 配置 +# REDIS_HOST=127.0.0.1 +# REDIS_PORT=6379 + +# 密钥配置(记得改) +SECRET_KEY = 'pear-admin-flask' + +# 邮箱配置 +MAIL_SERVER = 'smtp.qq.com' +MAIL_USERNAME = '123@qq.com' +MAIL_PASSWORD = 'XXXXX' # 生成的授权码 + +# 插件配置 +PLUGIN_ENABLE_FOLDERS = ["helloworld"] \ No newline at end of file -- Gitee From e2ec08df6226be1257bd61281d2556bf263e2a6d Mon Sep 17 00:00:00 2001 From: wojiaoyishang <422880152@qq.com> Date: Sat, 11 Feb 2023 20:48:07 +0800 Subject: [PATCH 10/10] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- applications/common/utils/power.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/common/utils/power.py b/applications/common/utils/power.py index 99d2757..d6b5b0b 100644 --- a/applications/common/utils/power.py +++ b/applications/common/utils/power.py @@ -60,7 +60,7 @@ def add(parentId, powerName, powerType, icon, sort: int, enable: bool, powerCode 参考代码:: - dev.power.add("0", "测试", "1", "layui-icon-time", 0, True, "testfor", "https://baidu.com", "_iframe") + power.add("0", "测试", "1", "layui-icon-time", 0, True, "testfor", "https://baidu.com", "_iframe") :param parentId: 父ID,0为顶级菜单ID :param powerName: 菜单名称 -- Gitee