diff --git a/applications/extensions/__init__.py b/applications/extensions/__init__.py index 2e7e1086ebadfb551a787308fc96765c860d745f..6e354f9a07713ae7c8c32f554e072ccd697c2d51 100644 --- a/applications/extensions/__init__.py +++ b/applications/extensions/__init__.py @@ -5,7 +5,7 @@ from .init_login import init_login_manager from .init_debug_tool import init_debug_tool from .init_template_directives import init_template_directives from .init_error_views import init_error_views -from .init_mail import init_mail +from .init_mail import init_mail, mail as flask_mail from .init_apscheduler import init_scheduler from .init_upload import init_upload from .init_dotenv import init_dotenv diff --git a/applications/models/__init__.py b/applications/models/__init__.py index fe78e9cab37ec30665ff8601e6e974b7dffa3dab..d94b26539de13d4ef34542987f64fd1d72d236a3 100644 --- a/applications/models/__init__.py +++ b/applications/models/__init__.py @@ -6,4 +6,5 @@ from .admin_power import Power from .admin_role import Role from .admin_role_power import role_power from .admin_user import User -from .admin_user_role import user_role \ No newline at end of file +from .admin_user_role import user_role +from .admin_mail import Mail diff --git a/applications/models/admin_mail.py b/applications/models/admin_mail.py new file mode 100644 index 0000000000000000000000000000000000000000..d1f70706d4237c4804f18b99cc0cded425410ea9 --- /dev/null +++ b/applications/models/admin_mail.py @@ -0,0 +1,12 @@ +import datetime +from applications.extensions import db + + +class Mail(db.Model): + __tablename__ = 'admin_mail' + id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment='邮件编号') + receiver = db.Column(db.String(1024), comment='收件人邮箱') + subject = db.Column(db.String(128), comment='邮件主题') + content = db.Column(db.Text(), comment='邮件正文') + user_id = db.Column(db.Integer, comment='发送人id') + create_at = db.Column(db.DateTime, default=datetime.datetime.now, comment='创建时间') diff --git a/applications/schemas/__init__.py b/applications/schemas/__init__.py index 4b3fa951a910bf3cf6f87bd9a2259db43bd005f3..c8160cb113f680a75b64926e35bd661d785bebae 100644 --- a/applications/schemas/__init__.py +++ b/applications/schemas/__init__.py @@ -5,3 +5,4 @@ from .admin_dict import DictDataOutSchema, DictTypeOutSchema from .admin_dept import DeptOutSchema from .admin_log import LogOutSchema from .admin_photo import PhotoOutSchema +from .admin_mail import MailOutSchema diff --git a/applications/schemas/admin_mail.py b/applications/schemas/admin_mail.py new file mode 100644 index 0000000000000000000000000000000000000000..9f089f9fd3a332a0a9dde412abc0ea8fa1fb89e5 --- /dev/null +++ b/applications/schemas/admin_mail.py @@ -0,0 +1,19 @@ +from applications.extensions import ma +from marshmallow import fields +from applications.models import User + + +# 用户models的序列化类 +class MailOutSchema(ma.Schema): + id = fields.Integer() + receiver = fields.Str() + subject = fields.Str() + content = fields.Str() + realname = fields.Method("get_realname") + create_at = fields.DateTime() + + def get_realname(self, obj): + if obj.user_id != None: + return User.query.filter_by(id=obj.user_id).first().realname + else: + return None diff --git a/applications/view/admin/__init__.py b/applications/view/admin/__init__.py index 9b58fcca622e93bbeef7ecd5a43576355d1e06f6..434713637c572b7374fe0b1d94142292006d4bb9 100644 --- a/applications/view/admin/__init__.py +++ b/applications/view/admin/__init__.py @@ -9,6 +9,7 @@ from applications.view.admin.role import admin_role from applications.view.admin.user import admin_user from applications.view.admin.monitor import admin_monitor_bp from applications.view.admin.task import admin_task +from applications.view.admin.mail import admin_mail def register_admin_views(app: Flask): @@ -21,3 +22,4 @@ def register_admin_views(app: Flask): app.register_blueprint(admin_role) app.register_blueprint(admin_dict) app.register_blueprint(admin_task) + app.register_blueprint(admin_mail) diff --git a/applications/view/admin/mail.py b/applications/view/admin/mail.py new file mode 100644 index 0000000000000000000000000000000000000000..eafe1e27af33ec474f7e2e02f30bc8ab095e6add --- /dev/null +++ b/applications/view/admin/mail.py @@ -0,0 +1,99 @@ +from flask import Blueprint, render_template, request, current_app +from flask_login import current_user +from flask_mail import Message + +from applications.common.curd import model_to_dicts +from applications.common.helper import ModelFilter +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 xss_escape +from applications.extensions import db, flask_mail +from applications.models import Mail +from applications.schemas import MailOutSchema + +admin_mail = Blueprint('adminMail', __name__, url_prefix='/admin/mail') + + +# 用户管理 +@admin_mail.get('/') +@authorize("admin:mail:main", log=True) +def main(): + return render_template('admin/mail/main.html') + + +# 用户分页查询 +@admin_mail.get('/data') +@authorize("admin:mail:main", log=True) +def data(): + # 获取请求参数 + receiver = xss_escape(request.args.get("receiver")) + subject = xss_escape(request.args.get('subject')) + content = xss_escape(request.args.get('content')) + # 查询参数构造 + 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() + count = mail.total + # 返回api + return table_api(data=model_to_dicts(schema=MailOutSchema, data=mail.items), count=count) + + +# 用户增加 +@admin_mail.get('/add') +@authorize("admin:mail:add", log=True) +def add(): + return render_template('admin/mail/add.html') + + +@admin_mail.post('/save') +@authorize("admin:mail:add", log=True) +def save(): + req_json = request.json + receiver = xss_escape(req_json.get("receiver")) + subject = xss_escape(req_json.get('subject')) + content = xss_escape(req_json.get('content')) + user_id = current_user.id + + try: + msg = Message(subject=subject, recipients=receiver.split(";"), body=content) + flask_mail.send(msg) + except Exception as e: + current_app.log_exception(e) + return fail_api(msg="发送失败,请检查邮件配置或发送人邮箱是否写错") + + mail = Mail(receiver=receiver, subject=subject, content=content, user_id=user_id) + + db.session.add(mail) + db.session.commit() + return success_api(msg="增加成功") + + +# 删除用户 +@admin_mail.delete('/remove/') +@authorize("admin:mail:remove", log=True) +def delete(id): + res = Mail.query.filter_by(id=id).delete() + if not res: + return fail_api(msg="删除失败") + db.session.commit() + return success_api(msg="删除成功") + + +# 批量删除 +@admin_mail.delete('/batchRemove') +@authorize("admin:mail:remove", log=True) +def batch_remove(): + ids = request.form.getlist('ids[]') + for id in ids: + res = Mail.query.filter_by(id=id).delete() + if not res: + return fail_api(msg="批量删除失败") + db.session.commit() + return success_api(msg="批量删除成功") diff --git a/templates/admin/mail/add.html b/templates/admin/mail/add.html new file mode 100644 index 0000000000000000000000000000000000000000..e28a55af6b918b5863c32d6ba735055e5766fab3 --- /dev/null +++ b/templates/admin/mail/add.html @@ -0,0 +1,80 @@ + + + + 邮件管理 + {% include 'admin/common/header.html' %} + + +
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+
+
+ + +
+
+
+{% include 'admin/common/footer.html' %} + + + + \ No newline at end of file diff --git a/templates/admin/mail/main.html b/templates/admin/mail/main.html new file mode 100644 index 0000000000000000000000000000000000000000..19dfaf90d78c8b10b8e55613d2860ec194c2f518 --- /dev/null +++ b/templates/admin/mail/main.html @@ -0,0 +1,230 @@ + + + + 邮件管理 + {% include 'admin/common/header.html' %} + + + +{# 查询表单 #} +
+
+
+
+ +
+ +
+ +
+ +
+ +
+ +
+ + +
+
+
+
+{# 用户表格 #} +
+
+
+
+
+
+
+ +{# 表格操作 #} + + +{# 用户修改操作 #} + + +{# 启动与禁用 #} + + +{# 用户注册时间 #} + + +{% include 'admin/common/footer.html' %} + + + \ No newline at end of file diff --git a/test/pear.sql b/test/pear.sql index 3774049fe550eaaf621a99c08dd1cd5b572ac875..6c29bc4093c40c7d2df1ea1e2ff83d153086afd3 100644 --- a/test/pear.sql +++ b/test/pear.sql @@ -110,6 +110,28 @@ CREATE TABLE `admin_dict_type` ( -- ---------------------------- INSERT INTO `admin_dict_type` VALUES (1, '用户性别', 'user_sex', '用户性别', 1, NULL, '2021-04-16 13:37:11'); +-- ---------------------------- +-- Table structure for admin_mail +-- ---------------------------- +DROP TABLE IF EXISTS `admin_mail`; +CREATE TABLE `admin_mail` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '邮件编号', + `receiver` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '收件人邮箱', + `subject` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '邮件主题', + `content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '邮件正文', + `user_id` int(11) NULL DEFAULT NULL COMMENT '发送人id', + `create_at` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 17 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of admin_mail +-- ---------------------------- +INSERT INTO `admin_mail` VALUES (1, '1242733702@qq.com', 'pear-admin-flask', 'pear-admin-flask', 1, '2022-10-11 13:41:21'); +INSERT INTO `admin_mail` VALUES (4, '1242733702@qq.com', '湖人总冠军', '湖人总冠军', 1, '2022-10-11 14:03:30'); +INSERT INTO `admin_mail` VALUES (5, '1242733702@qq.com', '这是flask测试邮箱', '正文', 1, '2022-10-11 14:10:30'); + + -- ---------------------------- -- Table structure for admin_photo -- ---------------------------- @@ -186,6 +208,9 @@ INSERT INTO `admin_power` VALUES (53, '任务管理', '1', 'admin:task:main', '/ INSERT INTO `admin_power` VALUES (54, '任务增加', '2', 'admin:task:add', '', '', '53', 'layui-icon ', 1, '2021-06-22 22:20:54', '2021-06-22 22:20:54', 1); INSERT INTO `admin_power` VALUES (55, '任务修改', '2', 'admin:task:edit', '', '', '53', 'layui-icon ', 2, '2021-06-22 22:21:34', '2021-06-22 22:21:34', 1); INSERT INTO `admin_power` VALUES (56, '任务删除', '2', 'admin:task:remove', '', '', '53', 'layui-icon ', 3, '2021-06-22 22:22:18', '2021-06-22 22:22:18', 1); +INSERT INTO `admin_power` VALUES (57, '邮件管理', '1', 'admin:mail:main', '/admin/mail', '_iframe', '1', 'layui-icon layui-icon layui-icon-release', 7, '2022-10-11 11:21:05', '2022-10-11 11:21:22', 1); +INSERT INTO `admin_power` VALUES (58, '邮件发送', '2', 'admin:mail:add', '', '', '57', 'layui-icon layui-icon-ok-circle', 1, '2022-10-11 11:22:26', '2022-10-11 11:22:26', 1); +INSERT INTO `admin_power` VALUES (59, '邮件删除', '2', 'admin:mail:remove', '', '', '57', 'layui-icon layui-icon layui-icon-close', 2, '2022-10-11 11:23:06', '2022-10-11 11:23:18', 1); -- ---------------------------- -- Table structure for admin_role @@ -271,6 +296,9 @@ INSERT INTO `admin_role_power` VALUES (363, 53, 1); INSERT INTO `admin_role_power` VALUES (364, 54, 1); INSERT INTO `admin_role_power` VALUES (365, 55, 1); INSERT INTO `admin_role_power` VALUES (366, 56, 1); +INSERT INTO `admin_role_power` VALUES (367, 57, 1); +INSERT INTO `admin_role_power` VALUES (368, 58, 1); +INSERT INTO `admin_role_power` VALUES (369, 59, 1); -- ---------------------------- -- Table structure for admin_user