Files
xianyan/lib/features/auth/services/email_service.dart
Developer 00ff5f152a feat: 添加清除结果功能到检查提供者
refactor: 更新URL哈希处理逻辑

feat: 添加聊天消息存储支持

docs: 更新API控制器基类文档

chore: 删除无用脚本文件

fix: 修复分类模型返回类型问题

feat: 添加回执登录功能

build: 更新依赖项配置

style: 统一HTML模板中的哈希ID引用格式

ci: 添加部署和检查脚本
2026-04-30 10:19:56 +08:00

120 lines
4.0 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/// ============================================================
/// 闲言APP — 邮箱验证码服务
/// 创建时间: 2026-04-30
/// 更新时间: 2026-04-30
/// 作用: 本地SMTP发送验证码邮件配合回执验证机制
/// 上次更新: 初始创建使用mailer库通过SMTP发送验证码
/// ============================================================
import 'dart:math';
import 'package:mailer/mailer.dart';
import 'package:mailer/smtp_server.dart';
import '../../../core/utils/logger.dart';
class EmailService {
EmailService._();
static const String _smtpHost = 'free.mboxhosting.com';
static const int _smtpPort = 465;
static const String _username = 'gg@0gg.cc';
static const String _password = '520kiss123';
static const String _fromEmail = 'gg@0gg.cc';
static const String _fromName = '闲言APP';
static String? _pendingCode;
static String? _pendingEmail;
static DateTime? _codeExpireTime;
static String generateCode() {
final random = Random.secure();
return List.generate(6, (_) => random.nextInt(10)).join();
}
static Future<bool> sendVerificationCode({
required String toEmail,
required String code,
}) async {
try {
final smtpServer = SmtpServer(
_smtpHost,
port: _smtpPort,
username: _username,
password: _password,
ssl: true,
);
final message = Message()
..from = const Address(_fromEmail, _fromName)
..recipients.add(Address(toEmail))
..subject = '闲言APP 验证码'
..html = _buildEmailHtml(code);
final sendReport = await send(message, smtpServer);
Log.i('验证码邮件发送成功: ${sendReport.toString()}');
_pendingCode = code;
_pendingEmail = toEmail;
_codeExpireTime = DateTime.now().add(const Duration(minutes: 5));
return true;
} catch (e) {
Log.e('验证码邮件发送失败', e);
return false;
}
}
static bool verifyCode({required String email, required String code}) {
if (_pendingCode == null || _pendingEmail == null) return false;
if (_codeExpireTime != null && DateTime.now().isAfter(_codeExpireTime!)) {
_clear();
return false;
}
if (_pendingEmail != email || _pendingCode != code) return false;
_clear();
return true;
}
static void _clear() {
_pendingCode = null;
_pendingEmail = null;
_codeExpireTime = null;
}
static String _buildEmailHtml(String code) {
return '''
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body style="margin:0;padding:0;background:#f5f5f7;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;">
<table width="100%" cellpadding="0" cellspacing="0" style="background:#f5f5f7;padding:40px 0;">
<tr><td align="center">
<table width="480" cellpadding="0" cellspacing="0" style="background:#fff;border-radius:16px;overflow:hidden;box-shadow:0 2px 12px rgba(0,0,0,0.08);">
<tr><td style="background:linear-gradient(135deg,#007AFF,#5856D6);padding:32px;text-align:center;">
<h1 style="margin:0;color:#fff;font-size:24px;font-weight:700;">✨ 闲言APP</h1>
</td></tr>
<tr><td style="padding:32px;">
<p style="margin:0 0 8px;font-size:16px;color:#1d1d1f;font-weight:600;">验证你的邮箱</p>
<p style="margin:0 0 24px;font-size:14px;color:#86868b;">请使用以下验证码完成操作5分钟内有效</p>
<table cellpadding="0" cellspacing="0" style="margin:0 auto 24px;"><tr>
<td style="background:#f5f5f7;border-radius:12px;padding:16px 32px;text-align:center;">
<span style="font-size:36px;font-weight:700;letter-spacing:8px;color:#007AFF;">$code</span>
</td></tr></table>
<p style="margin:0;font-size:12px;color:#86868b;text-align:center;">如非本人操作,请忽略此邮件</p>
</td></tr>
<tr><td style="padding:16px 32px;background:#f5f5f7;text-align:center;">
<p style="margin:0;font-size:11px;color:#86868b;">© 闲言APP · 安全验证</p>
</td></tr>
</table>
</td></tr>
</table>
</body>
</html>
''';
}
}