Browse Source

🎈 perf: 优化邮件格式

Pchen. 2 months ago
parent
commit
007f574712
4 changed files with 213 additions and 43 deletions
  1. 20 39
      apis/Captcha/SendEmail.js
  2. 3 3
      apis/User/Register.js
  3. 1 1
      plugin/Email/Email.js
  4. 189 0
      plugin/Email/emailTemplate.js

+ 20 - 39
apis/Captcha/SendEmail.js

@@ -1,69 +1,50 @@
-const API = require("../../lib/API");
-const { BaseStdResponse } = require("../../BaseStdResponse");
-const Redis = require('../../plugin/DataBase/Redis');
-const sendEmail = require('../../plugin/Email/Email');
+const API = require("../../lib/API")
+const { BaseStdResponse } = require("../../BaseStdResponse")
+const Redis = require('../../plugin/DataBase/Redis')
+const EmailTemplate = require('../../plugin/Email/emailTemplate')
 
 // 发送邮箱验证码
 class SendEmail extends API {
     constructor() {
-        super();
+        super()
 
-        this.setMethod("POST");
-        this.setPath("/Captcha/SendEmail");
+        this.setMethod("POST")
+        this.setPath("/Captcha/SendEmail")
     }
 
     async onRequest(req, res) {
-        const { email, text, id, type } = req.body;
+        const { email, text, id, type } = req.body
 
-        if ([email, text, id, type].some(value => value === '' || value === null || value === undefined)) {
-            res.json({
+        if ([email, text, id, type].some(value => value === '' || value === null || value === undefined))
+            return res.json({
                 ...BaseStdResponse.MISSING_PARAMETER,
                 endpoint: 1513126
-            });
-            return;
-        }
-
+            })
+            
         try {
-            const code = await Redis.get(`captcha:${id}`);
+            const code = await Redis.get(`captcha:${id}`)
             if (!code || code != text.toLowerCase())
                 return res.json({
                     ...BaseStdResponse.SMS_CHECK_FAIL,
                     msg: '验证码输入错误或已过期'
                 })
 
-            await Redis.del(`captcha:${id}`);
+            await Redis.del(`captcha:${id}`)
         } catch (err) {
-            this.logger.error(`验证图片验证码失败!${err.stack}`);
+            this.logger.error(`验证图片验证码失败!${err.stack}`)
             return res.json({
                 ...BaseStdResponse.DATABASE_ERR,
                 msg: '验证失败!'
             })
         }
 
-        let content;
-        switch (type) {
-            case 'register':
-                content = '您正在注册GitNexus账号,';
-                break;
-            case 'forget':
-                content = '您正在找回GitNexus账号,';
-                break;
-            case 'bind':
-                content = '您正在进行换绑邮箱操作,';
-                break;
-            default:
-                return res.json({
-                    ...BaseStdResponse.METHOD_NOT_EXIST
-                })
-        }
-
-        const code = Math.random().toFixed(6).slice(-6);
+        const code = Math.random().toFixed(6).slice(-6)
         try {
             await Redis.set(`email:${email}`, code, {
                 EX: 600
-            });
+            })
         } catch (err) {
-            this.logger.error(`发送邮箱验证码失败!${err.stack}`);
+            this.logger.error(`发送邮箱验证码失败!${err.stack}`)
             return res.json({
                 ...BaseStdResponse.SMS_SEND_FAIL,
                 msg: '请检查邮箱格式后再试!'
@@ -75,8 +56,8 @@ class SendEmail extends API {
         })
 
         // 先返回后发送
-        await sendEmail(email, '验证码', `${content}您的验证码为:${code}。此验证码10分钟内有效,请妥善保管您的验证码,非本人操作请忽略。`);
+        EmailTemplate.checkEmail(email, code)
     }
 }
 
-module.exports.SendEmail = SendEmail;
+module.exports.SendEmail = SendEmail

+ 3 - 3
apis/User/Register.js

@@ -4,7 +4,7 @@ const bcryptjs = require('bcryptjs');
 const { BaseStdResponse } = require("../../BaseStdResponse");
 const db = require("../../plugin/DataBase/db");
 const Redis = require('../../plugin/DataBase/Redis');
-const sendEmail = require('../../plugin/Email/Email');
+const EmailTemplate = require('../../plugin/Email/emailTemplate')
 
 // 用户注册
 class Register extends API {
@@ -102,8 +102,8 @@ class Register extends API {
 
             res.json({
                 ...BaseStdResponse.OK
-            });
-            await sendEmail(email, '账号注册成功', `您已成功注册GitNexus账号,用户名${username},注册时间:${new Date().toLocaleString()}`);
+            })
+            await EmailTemplate.registerSuccess(email, username)
         } else {
             res.json({ ...BaseStdResponse.ERR, endpoint: 7894378, msg: '注册失败!'});
         }

+ 1 - 1
plugin/Email/Email.js

@@ -21,7 +21,7 @@ async function sendEmail(email, subject, content) {
             from: `GitNexus <${transporter.options.auth.user}>`,
             to: email,
             subject: subject,
-            text: content
+            html: content
         }
         try {
             transporter.sendMail(mail, (error) => {

+ 189 - 0
plugin/Email/emailTemplate.js

@@ -0,0 +1,189 @@
+const sendEmail = require('./Email')
+
+class emailTemplate {
+    stramptoTime(time) {
+        if (time < 10)
+            return '';
+        return new Date(+time).toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' });
+    }
+
+    async checkEmail(email, code) {
+        const time = new Date().getTime()
+        await sendEmail(email, 'GitNexus - 邮箱验证码',
+            `<html lang="zh-CN">
+
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>GitNexus - 邮箱验证码</title>
+    <style>
+        body {
+            font-family: Arial, sans-serif;
+            background-color: #f4f4f4;
+            margin: 0;
+            padding: 0;
+        }
+
+        .container {
+            width: 80%;
+            margin: 20px auto;
+            background-color: #fff;
+            padding: 20px;
+            border-radius: 8px;
+            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
+        }
+
+        .head {
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            gap:10px;
+            color: #2c3e50;
+        }
+
+        p {
+            font-size: 16px;
+            color: #34495e;
+            line-height: 1.6;
+            text-indent: 2em;
+        }
+
+        .code {
+            margin: 20px 0;
+            font-size: 1.5em;
+            text-align: center;
+            font-weight: bold;
+        }
+
+        .important {
+            color: #e74c3c;
+            font-weight: bold;
+        }
+
+        .footer {
+            font-size: 14px;
+            text-align: center;
+            color: #7f8c8d;
+            margin-top: 50px;
+        }
+    </style>
+</head>
+
+<body>
+    <div class="container">
+        <div class="head">
+            <svg t="1743769783333" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2616" width="32" height="32"><path d="M512 0C229.23264 0 0 229.23264 0 512c0 282.76736 229.23264 512 512 512 51.623253 0 101.451093-7.673173 148.43904-21.886293 127.91808-38.68672 234.666667-126.07488 298.707627-240.59904 25.78432-46.107307 44.632747-96.610987 55.166293-150.09792 0.054613-0.273067 0.12288-0.53248 0.177493-0.805547C1020.7232 578.70336 1024 545.737387 1024 512 1024 229.23264 794.76736 0 512 0zM823.958187 542.180693l-281.750187 281.750187c-16.329387 16.308907-42.769067 16.308907-59.06432 0L215.69536 556.516693l-12.192427-12.192427-3.46112-3.46112c-16.308907-16.308907-16.308907-42.728107 0-59.057493l132.87424-132.860587 0.34816-0.34816 54.12864-54.114987 49.493333 49.493333c-3.80928 7.92576-5.9392 16.820907-5.9392 26.200747 0 26.48064 16.91648 48.96768 40.523093 57.316693l0 169.04192c-23.606613 8.349013-40.523093 30.856533-40.523093 57.316693 0 33.573547 27.211093 60.78464 60.78464 60.78464s60.78464-27.211093 60.78464-60.78464c0-26.48064-16.923307-48.96768-40.523093-57.316693L511.993173 427.47904c2.02752-0.709973 4.007253-1.51552 5.9392-2.450773l81.025707 81.025707c-3.80928 7.92576-5.9392 16.820907-5.9392 26.200747 0 33.573547 27.211093 60.78464 60.78464 60.78464 33.573547 0 60.78464-27.211093 60.78464-60.78464 0-33.573547-27.211093-60.78464-60.78464-60.78464-9.37984 0-18.254507 2.1504-26.200747 5.9392L546.583893 396.383573c3.80928-7.92576 5.9392-16.820907 5.9392-26.200747 0-33.573547-27.211093-60.78464-60.78464-60.78464-9.37984 0-18.254507 2.1504-26.200747 5.9392l-49.493333-49.493333 27.613867-27.613867 0.211627-0.211627 10.67008-10.67008 27.27936-27.27936c16.329387-16.308907 42.769067-16.308907 59.057493 0l76.32896 76.322133 19.203413 19.196587 187.55584 187.542187 0-0.02048C840.267093 499.411627 840.267093 525.871787 823.958187 542.180693z" p-id="2617" fill="#1296db"></path></svg>
+            <h2>GitNexus - 邮箱验证码</h2>
+        </div>
+        
+        <p>尊敬的用户:</p>
+        <p>您正在本站进行邮箱验证操作,如非您本人操作,请忽略此邮件。</p>
+        <p>您的验证码为:</p>
+        <div class="code">
+            ${code}
+        </div>
+        <p class="important">验证码5分钟内有效,超时请重新获取</p>
+        <p class="footer">Copyright © 2025 Gitnexus.cn</p>
+    </div>
+</body>
+
+</html>`
+        )
+    }
+
+    async registerSuccess(email, username) {
+        const time = new Date().getTime()
+        await sendEmail(email, '您已成功注册GitNexus账号',
+            `<html lang="zh-CN">
+
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>GitNexus - 邮箱验证码</title>
+    <style>
+        body {
+            font-family: Arial, sans-serif;
+            background-color: #f4f4f4;
+            margin: 0;
+            padding: 0;
+        }
+
+        .container {
+            width: 80%;
+            margin: 20px auto;
+            background-color: #fff;
+            padding: 20px;
+            border-radius: 8px;
+            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
+        }
+
+        .head {
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            gap: 10px;
+            color: #2c3e50;
+        }
+
+        p {
+            font-size: 16px;
+            color: #34495e;
+            line-height: 1.6;
+            text-indent: 2em;
+        }
+
+        .info {
+            background-color: #ecf0f1;
+            padding: 15px;
+            border-radius: 5px;
+            margin: 20px 0;
+        }
+
+        .info p {
+            margin: 5px 0;
+        }
+
+        .important {
+            color: #e74c3c;
+            font-weight: bold;
+        }
+
+        .footer {
+            font-size: 14px;
+            text-align: center;
+            color: #7f8c8d;
+            margin-top: 50px;
+        }
+    </style>
+</head>
+
+<body>
+    <div class="container">
+        <div class="head">
+            <svg t="1743769783333" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
+                p-id="2616" width="32" height="32">
+                <path
+                    d="M512 0C229.23264 0 0 229.23264 0 512c0 282.76736 229.23264 512 512 512 51.623253 0 101.451093-7.673173 148.43904-21.886293 127.91808-38.68672 234.666667-126.07488 298.707627-240.59904 25.78432-46.107307 44.632747-96.610987 55.166293-150.09792 0.054613-0.273067 0.12288-0.53248 0.177493-0.805547C1020.7232 578.70336 1024 545.737387 1024 512 1024 229.23264 794.76736 0 512 0zM823.958187 542.180693l-281.750187 281.750187c-16.329387 16.308907-42.769067 16.308907-59.06432 0L215.69536 556.516693l-12.192427-12.192427-3.46112-3.46112c-16.308907-16.308907-16.308907-42.728107 0-59.057493l132.87424-132.860587 0.34816-0.34816 54.12864-54.114987 49.493333 49.493333c-3.80928 7.92576-5.9392 16.820907-5.9392 26.200747 0 26.48064 16.91648 48.96768 40.523093 57.316693l0 169.04192c-23.606613 8.349013-40.523093 30.856533-40.523093 57.316693 0 33.573547 27.211093 60.78464 60.78464 60.78464s60.78464-27.211093 60.78464-60.78464c0-26.48064-16.923307-48.96768-40.523093-57.316693L511.993173 427.47904c2.02752-0.709973 4.007253-1.51552 5.9392-2.450773l81.025707 81.025707c-3.80928 7.92576-5.9392 16.820907-5.9392 26.200747 0 33.573547 27.211093 60.78464 60.78464 60.78464 33.573547 0 60.78464-27.211093 60.78464-60.78464 0-33.573547-27.211093-60.78464-60.78464-60.78464-9.37984 0-18.254507 2.1504-26.200747 5.9392L546.583893 396.383573c3.80928-7.92576 5.9392-16.820907 5.9392-26.200747 0-33.573547-27.211093-60.78464-60.78464-60.78464-9.37984 0-18.254507 2.1504-26.200747 5.9392l-49.493333-49.493333 27.613867-27.613867 0.211627-0.211627 10.67008-10.67008 27.27936-27.27936c16.329387-16.308907 42.769067-16.308907 59.057493 0l76.32896 76.322133 19.203413 19.196587 187.55584 187.542187 0-0.02048C840.267093 499.411627 840.267093 525.871787 823.958187 542.180693z"
+                    p-id="2617" fill="#1296db"></path>
+            </svg>
+            <h2>GitNexus - 邮箱验证码</h2>
+        </div>
+
+        <p>尊敬的 ${username}:</p>
+        <p>您已成功注册GitNexus账号:</p>
+        <div class="info">
+            <p><strong>用户名:</strong> ${username}</p>
+            <p><strong>注册时间:</strong> ${this.stramptoTime(time)}</p>
+        </div>
+
+        <p class="footer">Copyright © 2025 Gitnexus.cn</p>
+    </div>
+</body>
+
+</html>`
+        )
+    }
+}
+
+const EmailTemplate = new emailTemplate()
+module.exports = EmailTemplate