106 lines
3.8 KiB
Python
106 lines
3.8 KiB
Python
# sunderer_app/sunderer_app/api.py
|
|
import frappe
|
|
from frappe.utils import random_string, now_datetime, add_to_date
|
|
import secrets
|
|
import string
|
|
|
|
@frappe.whitelist(allow_guest=True)
|
|
def generate_verification_code(length=6):
|
|
"""生成指定长度的数字验证码"""
|
|
code = ''.join([str(secrets.randbelow(10)) for _ in range(length)])
|
|
return code
|
|
|
|
@frappe.whitelist(allow_guest=True)
|
|
def send_verification_email(email, verification_code):
|
|
"""发送验证码邮件"""
|
|
try:
|
|
# 邮件标题
|
|
subject = "决裂者终端 - 验证码"
|
|
|
|
# 邮件内容
|
|
message = f"""
|
|
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
|
|
<h2 style="color: #00AFFF;">决裂者终端</h2>
|
|
<p>您好!</p>
|
|
<p>您的验证码是:</p>
|
|
<div style="background: linear-gradient(135deg, #00AFFF, #0077CC);
|
|
padding: 20px;
|
|
border-radius: 10px;
|
|
text-align: center;
|
|
color: white;
|
|
font-size: 24px;
|
|
font-weight: bold;
|
|
letter-spacing: 5px;
|
|
margin: 20px 0;">
|
|
{verification_code}
|
|
</div>
|
|
<p>此验证码将在 10 分钟内有效。</p>
|
|
<p>如果您没有请求此验证码,请忽略此邮件。</p>
|
|
<hr style="margin: 20px 0; border: none; border-top: 1px solid #ccc;">
|
|
<p style="color: #666; font-size: 12px;">© 2026 Sunderer Games. All rights reserved.</p>
|
|
</div>
|
|
"""
|
|
|
|
# 发送邮件
|
|
frappe.sendmail(
|
|
recipients=[email],
|
|
subject=subject,
|
|
message=message,
|
|
delayed=False # 立即发送
|
|
)
|
|
|
|
return {"success": True, "message": "验证码已发送到您的邮箱"}
|
|
except Exception as e:
|
|
frappe.log_error(f"发送验证码邮件失败: {str(e)}")
|
|
return {"success": False, "message": str(e)}
|
|
|
|
@frappe.whitelist(allow_guest=True)
|
|
def send_signup_code(email):
|
|
"""发送注册验证码的主函数"""
|
|
try:
|
|
# 验证邮箱格式
|
|
import re
|
|
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
|
|
if not re.match(pattern, email):
|
|
return {"exc": "请输入有效的邮箱地址!"}
|
|
|
|
# 生成验证码
|
|
verification_code = generate_verification_code(6)
|
|
|
|
# 将验证码存储到缓存中(有效期10分钟)
|
|
cache_key = f"signup_code_{email}"
|
|
frappe.cache().set_value(cache_key, verification_code, expires_in_sec=600) # 10分钟
|
|
|
|
# 发送邮件
|
|
result = send_verification_email(email, verification_code)
|
|
|
|
if result["success"]:
|
|
return {"message": "验证码已发送到您的邮箱"}
|
|
else:
|
|
return {"exc": f"发送失败: {result['message']}"}
|
|
|
|
except Exception as e:
|
|
frappe.log_error(f"发送注册验证码失败: {str(e)}")
|
|
return {"exc": f"发送失败: {str(e)}"}
|
|
|
|
@frappe.whitelist(allow_guest=True)
|
|
def verify_signup_code(email, code):
|
|
"""验证注册验证码"""
|
|
try:
|
|
cache_key = f"signup_code_{email}"
|
|
stored_code = frappe.cache().get_value(cache_key)
|
|
|
|
if not stored_code:
|
|
return {"exc": "验证码已过期,请重新获取"}
|
|
|
|
if str(stored_code) != str(code):
|
|
return {"exc": "验证码错误"}
|
|
|
|
# 验证成功,清除缓存
|
|
frappe.cache().delete_value(cache_key)
|
|
|
|
return {"success": True}
|
|
|
|
except Exception as e:
|
|
frappe.log_error(f"验证注册验证码失败: {str(e)}")
|
|
return {"exc": f"验证失败: {str(e)}"} |