From 9164a360e717e56914526177be24f2c3d14e34e0 Mon Sep 17 00:00:00 2001 From: gingmzmzx <2417481092@qq.com> Date: Fri, 4 Oct 2024 15:54:02 +0800 Subject: [PATCH] feat: add broadcast mail --- vj4/handler/admin.py | 18 ++++++ vj4/handler/domain.py | 5 -- vj4/locale/zh_CN.yaml | 5 ++ vj4/ui/pages/admin_mail.page.js | 63 +++++++++++++++++++ vj4/ui/pages/admin_mail.page.styl | 9 +++ vj4/ui/templates/admin_base.html | 1 + vj4/ui/templates/admin_mail.html | 63 +++++++++++++++++++ vj4/ui/templates/broadcast_mail.html | 9 +++ vj4/ui/templates/bsod.html | 4 ++ .../partials/admin_send_mail_form.html | 3 + 10 files changed, 175 insertions(+), 5 deletions(-) create mode 100644 vj4/ui/pages/admin_mail.page.js create mode 100644 vj4/ui/pages/admin_mail.page.styl create mode 100644 vj4/ui/templates/admin_mail.html create mode 100644 vj4/ui/templates/broadcast_mail.html create mode 100644 vj4/ui/templates/partials/admin_send_mail_form.html diff --git a/vj4/handler/admin.py b/vj4/handler/admin.py index 1a3c876..0fcc8e7 100644 --- a/vj4/handler/admin.py +++ b/vj4/handler/admin.py @@ -63,3 +63,21 @@ async def post(self, *, uid: int): await user.set_priv(int(uid), privs) self.json_or_redirect(self.reverse_url("admin_user")) + +@app.route('/admin/mail', 'admin_mail') +class AdminMailHandler(base.OperationHandler): + @base.require_priv(builtin.PRIV_ADMIN) + async def get(self): + udocs = [] + async for udoc in user.get_multi(): + udocs.append(udoc) + self.render('admin_mail.html', udocs=udocs) + + @base.require_priv(builtin.PRIV_ADMIN) + @base.require_csrf_token + @base.sanitize + async def post_send_mail(self, *, uid: int, title: str, content: str): + udict = await user.get_by_uid(uid) + mail = udict['mail'] + await self.send_mail(mail, "通知 - "+str(title), "broadcast_mail.html", mail_content=content, mail_title=title) + self.json_or_redirect(self.url, mail=mail) diff --git a/vj4/handler/domain.py b/vj4/handler/domain.py index c1bb5b3..11db3de 100755 --- a/vj4/handler/domain.py +++ b/vj4/handler/domain.py @@ -26,11 +26,6 @@ from vj4.util import pagination -@app.route('/test/header', 'test_header') -class TestHeaderHandler(base.Handler): - async def get(self): - self.render('bsod.html', args=self.request.headers) - @app.route('/', 'domain_main') class DomainMainHandler(contest.ContestStatusMixin, base.OperationHandler): CONTESTS_ON_MAIN = 5 diff --git a/vj4/locale/zh_CN.yaml b/vj4/locale/zh_CN.yaml index c04a32f..3b616d1 100755 --- a/vj4/locale/zh_CN.yaml +++ b/vj4/locale/zh_CN.yaml @@ -10,6 +10,11 @@ Tools: 工具 admin_dashboard: 管理员面板 admin_user: 管理用户 admin_privilege: 管理特权 +admin_mail: 邮件广播 +Mail Content: 邮件内容 +Send mail to selected users: 发送邮件到指定用户 +Mail successfully sent to uid:{0}.: 发送邮件成功(UID:{0}) +Confirm sending Email to selected users?: 确定要给选定用户发送广播邮件? Updates Manager: 动态管理者 Collapse: 收起 Expand: 展开 diff --git a/vj4/ui/pages/admin_mail.page.js b/vj4/ui/pages/admin_mail.page.js new file mode 100644 index 0000000..0bc3f50 --- /dev/null +++ b/vj4/ui/pages/admin_mail.page.js @@ -0,0 +1,63 @@ +import _ from 'lodash'; + +import { NamedPage } from 'vj/misc/PageLoader'; +import Notification from 'vj/components/notification'; +import { ConfirmDialog } from 'vj/components/dialog'; + +import request from 'vj/utils/request'; +import tpl from 'vj/utils/tpl'; +import delay from 'vj/utils/delay'; +import i18n from 'vj/utils/i18n'; + +const page = new NamedPage('admin_mail', () => { + function ensureAndGetSelectedUsers() { + const users = _.map( + $('.admin_user_list tbody [type="checkbox"]:checked'), + ch => $(ch).closest('tr').attr('data-uid'), + ); + if (users.length === 0) { + Notification.error(i18n('Please select at least one user to perform this operation.')); + return null; + } + return users; + } + + async function sendMail(uid, title, content){ + try { + await request.post('', { + operation: 'send_mail', + uid: uid, + title: title, + content: content + }); + Notification.success(i18n('Mail successfully sent to uid:{0}.', uid)); + } catch (error) { + Notification.error(`Error uid:${uid} ${error.message}`); + } + } + + async function handleClickSend() { + const selectedUsers = ensureAndGetSelectedUsers(); + if (selectedUsers === null) { + return; + } + const action = await new ConfirmDialog({ + $body: tpl` +
${i18n('Confirm sending Email to selected users?')}
++ + | +{{ _('User ID') }} | +{{ _('Username') }} | +
---|---|---|
+ + | ++ {{ udoc['_id'] }} + | ++ {{ user.render_inline(udoc) }} + | +
+Debug Information
+
{{args}}
+