chenpei d0dc94e36d feat: 将弹幕功能替换为AI聊天助手
新功能:
- 创建AI聊天助手组件(AIChatWidget)
- 支持文字+图片多模态对话
- 集成Gemini AI API
- 支持图片编辑和内容生成
- 实时对话历史管理
- 优雅的UI设计,支持黑夜模式

技术实现:
- 后端API代理Gemini API(/api/ai-chat)
- 支持最多5张图片上传
- 流式响应处理
- 对话历史管理
- Base64图片处理

配置:
- 在.env中添加Gemini API配置
- GEMINI_API_KEY
- GEMINI_API_BASE_URL
- GEMINI_MODEL

替换原弹幕功能,提供更强大的AI助手体验!
2025-10-27 17:45:37 +08:00

118 lines
5.3 KiB
JavaScript
Executable File

const nodemailer = require('nodemailer');
const dotenv = require('dotenv');
dotenv.config();
/**
* 发送密码重置邮件
* @param {string} email - 收件人邮箱
* @param {string} resetLink - 重置密码链接
* @returns {Promise<void>}
*/
const sendResetPasswordEmail = async (email, resetLink) => {
try {
// 创建邮件发送器
const transporter = nodemailer.createTransport({
host: process.env.EMAIL_HOST || 'smtp.example.com',
port: parseInt(process.env.EMAIL_PORT || '587'),
secure: process.env.EMAIL_SECURE === 'true',
auth: {
user: process.env.EMAIL_USER || 'your-email@example.com',
pass: process.env.EMAIL_PASSWORD || 'your-email-password'
}
});
// 邮件内容
const mailOptions = {
from: `"${process.env.EMAIL_FROM_NAME || '支持团队'}" <${process.env.EMAIL_FROM || 'support@yourapp.com'}>`,
to: email,
subject: '密码重置请求',
text: `您收到这封邮件是因为您(或其他人)请求重置您账户的密码。\n\n`
+ `请点击下面的链接或将其复制到浏览器中以完成重置密码过程:\n\n`
+ `${resetLink}\n\n`
+ `此链接将在1小时后失效。\n\n`
+ `如果您没有请求此操作,请忽略此邮件,您的密码将保持不变。\n`,
html: `
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px; border: 1px solid #e0e0e0; border-radius: 5px;">
<h2 style="color: #333; text-align: center; border-bottom: 1px solid #eee; padding-bottom: 10px;">密码重置请求</h2>
<p>您好,</p>
<p>您收到这封邮件是因为我们收到了重置您账户密码的请求。</p>
<p>请点击下面的按钮完成密码重置:</p>
<div style="text-align: center; margin: 25px 0;">
<a href="${resetLink}" style="background-color: #4CAF50; color: white; padding: 10px 20px; text-decoration: none; border-radius: 4px; font-weight: bold;">重置密码</a>
</div>
<p>或者,您可以复制以下链接到浏览器地址栏:</p>
<p style="word-break: break-all; background-color: #f5f5f5; padding: 10px; border-radius: 4px;">${resetLink}</p>
<p><strong>注意:</strong> 此链接将在1小时后失效。</p>
<p>如果您没有请求重置密码,请忽略此邮件,您的密码将保持不变。</p>
<div style="margin-top: 30px; padding-top: 15px; border-top: 1px solid #eee; text-align: center; color: #777; font-size: 12px;">
<p>此邮件由系统自动发送,请勿直接回复。</p>
<p>© ${new Date().getFullYear()} 由壹点AIGC. 保留所有权利。</p>
</div>
</div>
`
};
// 发送邮件
await transporter.sendMail(mailOptions);
console.log(`密码重置邮件已发送到: ${email}`);
} catch (error) {
console.error('发送密码重置邮件失败:', error);
throw new Error('发送密码重置邮件失败,请检查邮件配置或稍后重试');
}
};
/**
* 发送密码重置成功通知邮件
* @param {string} email - 收件人邮箱
* @returns {Promise<void>}
*/
const sendPasswordResetSuccessEmail = async (email) => {
try {
// 创建邮件发送器
const transporter = nodemailer.createTransport({
host: process.env.EMAIL_HOST || 'smtp.example.com',
port: parseInt(process.env.EMAIL_PORT || '587'),
secure: process.env.EMAIL_SECURE === 'true',
auth: {
user: process.env.EMAIL_USER || 'your-email@example.com',
pass: process.env.EMAIL_PASSWORD || 'your-email-password'
}
});
// 邮件内容
const mailOptions = {
from: `"${process.env.EMAIL_FROM_NAME || '支持团队'}" <${process.env.EMAIL_FROM || 'support@yourapp.com'}>`,
to: email,
subject: '密码重置成功',
text: `您的密码已成功重置。\n\n`
+ `如果这不是您执行的操作,请立即联系我们的支持团队。\n`,
html: `
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px; border: 1px solid #e0e0e0; border-radius: 5px;">
<h2 style="color: #333; text-align: center; border-bottom: 1px solid #eee; padding-bottom: 10px;">密码重置成功</h2>
<p>您好,</p>
<p>您的账户密码已成功重置。</p>
<p>您现在可以使用新密码登录您的账户。</p>
<p>如果这不是您执行的操作,请立即联系我们的支持团队。</p>
<div style="margin-top: 30px; padding-top: 15px; border-top: 1px solid #eee; text-align: center; color: #777; font-size: 12px;">
<p>此邮件由系统自动发送,请勿直接回复。</p>
<p>© ${new Date().getFullYear()} 由壹点AIGC. 保留所有权利。</p>
</div>
</div>
`
};
// 发送邮件
await transporter.sendMail(mailOptions);
console.log(`密码重置成功通知邮件已发送到: ${email}`);
} catch (error) {
console.error('发送密码重置成功通知邮件失败:', error);
// 这里不抛出错误,因为这只是一个通知邮件,不应阻止主流程
console.log('发送密码重置成功通知邮件失败,但不影响密码重置流程');
}
};
module.exports = {
sendResetPasswordEmail,
sendPasswordResetSuccessEmail
};