优化邮件发送功能和支付宝支付诊断
- 修复邮件服务区域配置(改为ap-hongkong) - 增强支付宝支付错误诊断和日志 - 修复代码质量问题(OrderService、ImageToVideoTask) - 添加支付宝支付问题排查文档 - 增加详细的错误诊断信息
This commit is contained in:
144
demo/ALIPAY_PAYMENT_TROUBLESHOOTING.md
Normal file
144
demo/ALIPAY_PAYMENT_TROUBLESHOOTING.md
Normal file
@@ -0,0 +1,144 @@
|
||||
# 支付宝支付问题诊断指南
|
||||
|
||||
## 当前问题
|
||||
|
||||
根据日志显示,支付宝API调用出现 **"Read timed out"** 错误。
|
||||
|
||||
## 可能的原因
|
||||
|
||||
### 1. 网络连接问题
|
||||
- **网络延迟过高**:从本地到支付宝沙箱服务器(openapi.alipaydev.com)的网络延迟可能超过60秒
|
||||
- **网络不稳定**:网络连接可能间歇性中断
|
||||
|
||||
### 2. 支付宝沙箱环境问题
|
||||
- **服务响应慢**:支付宝沙箱环境可能响应较慢或不稳定
|
||||
- **服务暂时不可用**:沙箱环境可能正在维护
|
||||
|
||||
### 3. 防火墙或代理问题
|
||||
- **防火墙阻止**:本地防火墙可能阻止对支付宝API的访问
|
||||
- **代理服务器配置**:如果使用代理,可能需要配置代理设置
|
||||
|
||||
### 4. ngrok隧道问题
|
||||
- **隧道过期**:ngrok免费隧道可能已过期或不可用
|
||||
- **通知URL不可达**:支付宝无法访问通知URL,可能导致超时
|
||||
|
||||
## 诊断步骤
|
||||
|
||||
### 1. 检查网络连接
|
||||
|
||||
```powershell
|
||||
# 测试能否连接到支付宝沙箱服务器
|
||||
ping openapi.alipaydev.com
|
||||
|
||||
# 测试DNS解析
|
||||
nslookup openapi.alipaydev.com
|
||||
```
|
||||
|
||||
### 2. 检查ngrok隧道
|
||||
|
||||
```powershell
|
||||
# 检查ngrok是否运行
|
||||
Get-Process -Name ngrok -ErrorAction SilentlyContinue
|
||||
|
||||
# 访问ngrok控制面板查看隧道状态
|
||||
# 浏览器打开: http://127.0.0.1:4040
|
||||
```
|
||||
|
||||
### 3. 测试网络可达性
|
||||
|
||||
```powershell
|
||||
# 使用PowerShell测试HTTPS连接
|
||||
$url = "https://openapi.alipaydev.com/gateway.do"
|
||||
try {
|
||||
$response = Invoke-WebRequest -Uri $url -Method GET -TimeoutSec 10
|
||||
Write-Host "连接成功: $($response.StatusCode)"
|
||||
} catch {
|
||||
Write-Host "连接失败: $($_.Exception.Message)"
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 检查防火墙设置
|
||||
|
||||
确保防火墙允许以下连接:
|
||||
- 出站连接:`openapi.alipaydev.com:443`
|
||||
- 如果有ngrok,确保ngrok可访问
|
||||
|
||||
## 解决方案
|
||||
|
||||
### 方案1: 增加超时时间(已实施)
|
||||
|
||||
已在代码中将超时时间从30秒增加到60秒:
|
||||
- 连接超时:60秒
|
||||
- 读取超时:60秒
|
||||
|
||||
### 方案2: 检查ngrok配置
|
||||
|
||||
1. **确认ngrok隧道运行**
|
||||
```bash
|
||||
ngrok http 8080
|
||||
```
|
||||
|
||||
2. **更新配置文件中的URL**
|
||||
```properties
|
||||
alipay.notify-url=https://YOUR-NGROK-URL/api/payments/alipay/notify
|
||||
alipay.return-url=https://YOUR-NGROK-URL/api/payments/alipay/return
|
||||
```
|
||||
|
||||
3. **重新编译并重启服务**
|
||||
|
||||
### 方案3: 使用代理或VPN
|
||||
|
||||
如果网络环境限制了对支付宝服务器的访问:
|
||||
1. 配置HTTP代理
|
||||
2. 或使用VPN连接到支持的地区
|
||||
|
||||
### 方案4: 检查支付宝沙箱配置
|
||||
|
||||
1. **登录支付宝开放平台**:https://open.alipay.com/
|
||||
2. **检查应用配置**:
|
||||
- 应用ID是否正确
|
||||
- 密钥是否正确
|
||||
- 网关地址是否为沙箱地址:`https://openapi.alipaydev.com/gateway.do`
|
||||
|
||||
### 方案5: 测试开发模式
|
||||
|
||||
如果暂时无法连接到支付宝,可以考虑:
|
||||
1. 在开发环境中模拟支付宝响应
|
||||
2. 或暂时跳过支付功能进行其他功能的测试
|
||||
|
||||
## 当前配置
|
||||
|
||||
根据 `application-dev.properties`:
|
||||
|
||||
```properties
|
||||
alipay.app-id=9021000157616562
|
||||
alipay.gateway-url=https://openapi.alipaydev.com/gateway.do
|
||||
alipay.charset=UTF-8
|
||||
alipay.sign-type=RSA2
|
||||
alipay.notify-url=https://curtly-aphorismatic-ginger.ngrok-free.dev/api/payments/alipay/notify
|
||||
alipay.return-url=https://curtly-aphorismatic-ginger.ngrok-free.dev/api/payments/alipay/return
|
||||
```
|
||||
|
||||
## 日志分析
|
||||
|
||||
错误日志示例:
|
||||
```
|
||||
Read timed out
|
||||
```
|
||||
|
||||
这通常表示:
|
||||
- 网络连接建立成功
|
||||
- 但服务器在60秒内没有响应
|
||||
- 可能是服务器负载高或网络延迟
|
||||
|
||||
## 建议的排查顺序
|
||||
|
||||
1. ✅ **检查网络连接**:ping openapi.alipaydev.com
|
||||
2. ✅ **检查ngrok隧道**:确认隧道是否运行
|
||||
3. ✅ **查看详细日志**:重启服务后查看新增的诊断信息
|
||||
4. ⚠️ **如果问题持续**:考虑使用代理或联系支付宝技术支持
|
||||
|
||||
## 下一步
|
||||
|
||||
重新编译项目后,尝试创建支付订单,查看新的诊断日志输出,这将提供更详细的错误信息和解决建议。
|
||||
|
||||
66
demo/CODE_ISSUES_FIXED.md
Normal file
66
demo/CODE_ISSUES_FIXED.md
Normal file
@@ -0,0 +1,66 @@
|
||||
# 代码问题修复报告
|
||||
|
||||
## 修复的问题
|
||||
|
||||
### 1. **严重错误 - SystemSettings.vue 缺少结束标签** ✅ 已修复
|
||||
- **问题**: `SystemSettings.vue` 文件缺少 `</template>` 结束标签
|
||||
- **位置**: 第373行
|
||||
- **影响**: 导致 Vue 编译错误,前端无法正常运行
|
||||
- **修复**: 在第373行后添加了 `</template>` 和 `</div>` 标签
|
||||
|
||||
### 2. **OrderService.java - Switch 语句缺少枚举值处理** ✅ 已修复
|
||||
- **问题**: `updateOrderStatus` 方法中的 switch 语句缺少部分枚举值的处理
|
||||
- **位置**: `OrderService.java` 第166行
|
||||
- **影响**: 当订单状态为 `PENDING`, `CONFIRMED`, `PROCESSING`, `REFUNDED` 时,会触发编译警告
|
||||
- **修复**: 为所有 `OrderStatus` 枚举值添加了对应的 case 分支处理
|
||||
|
||||
### 3. **ImageToVideoTask.java - 潜在的 NullPointerException** ✅ 已修复
|
||||
- **问题**: `calculateCost()` 方法中直接使用 `duration`,可能出现空指针解包
|
||||
- **位置**: `ImageToVideoTask.java` 第94行
|
||||
- **影响**: 当 `duration` 为 null 时,可能出现 NullPointerException
|
||||
- **修复**: 添加了安全处理,先赋值给局部变量再使用
|
||||
|
||||
## 发现的警告(非严重)
|
||||
|
||||
### 1. **TencentSesMailService.java**
|
||||
- `fromName` 变量未使用 - 这是配置变量,保留用于未来扩展
|
||||
- 异常处理可以优化为 multicatch - 不影响功能
|
||||
|
||||
### 2. **PaymentService.java**
|
||||
- 第319行空指针警告 - 代码已有null检查,实际安全
|
||||
- 异常处理可以优化 - 不影响功能
|
||||
|
||||
### 3. **AlipayService.java**
|
||||
- 第144行可能的空指针 - 需要在调用前验证 response 是否为 null
|
||||
|
||||
### 4. **前端文件**
|
||||
- SystemSettings.vue 已修复
|
||||
- 其他警告多为代码风格建议,不影响功能
|
||||
|
||||
## 建议进一步优化
|
||||
|
||||
1. **AlipayService.java** - 添加 response 的 null 检查
|
||||
2. **异常处理优化** - 多个文件可以使用 Java 7+ 的 multicatch 语法
|
||||
3. **代码清理** - 移除未使用的导入和方法(标记为未使用本地的方法)
|
||||
4. **Switch 表达式** - 考虑使用 Java 14+ 的 switch 表达式简化代码
|
||||
|
||||
## 测试建议
|
||||
|
||||
1. **前端测试** - 验证 SystemSettings.vue 页面可以正常加载和渲染
|
||||
2. **订单状态测试** - 测试所有订单状态的转换是否正常工作
|
||||
3. **空值测试** - 测试 duration 为 null 的情况是否处理正确
|
||||
|
||||
## 已修复文件列表
|
||||
|
||||
- ✅ `demo/frontend/src/views/SystemSettings.vue`
|
||||
- ✅ `demo/src/main/java/com/example/demo/service/OrderService.java`
|
||||
- ✅ `demo/src/main/java/com/example/demo/model/ImageToVideoTask.java`
|
||||
|
||||
## 编译状态
|
||||
|
||||
所有修复后应能正常编译,建议重新编译验证:
|
||||
|
||||
```bash
|
||||
.\mvnw.cmd clean package -DskipTests
|
||||
```
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
- ✅ `tencent.ses.secret-id` - SecretID(已配置)
|
||||
- ✅ `tencent.ses.secret-key` - SecretKey(已配置)
|
||||
- ✅ `tencent.ses.region` - 服务区域(ap-beijing)
|
||||
- ✅ `tencent.ses.from-email` - 发信地址(noreply@vionow.com)
|
||||
- ✅ `tencent.ses.from-email` - 发信地址(newletter@vionow.com)
|
||||
- ✅ `tencent.ses.from-name` - 发件人名称(AIGC平台)
|
||||
- ✅ `tencent.ses.template-id` - 模板ID(当前为0,开发模式)
|
||||
- ✅ `tencent.ses.template-id` - 模板ID(154360,生产模式)
|
||||
|
||||
### 2. 代码实现
|
||||
- ✅ 邮箱验证码登录接口(`/api/auth/login/email`)
|
||||
@@ -50,18 +50,18 @@
|
||||
### 2. 发信地址验证 ⚠️ **重要(生产环境必需)**
|
||||
|
||||
**当前配置:**
|
||||
- 发信地址: `noreply@vionow.com`
|
||||
- 发信地址: `newletter@vionow.com`
|
||||
|
||||
**需要操作:**
|
||||
- [ ] **确认发信地址是否已验证**
|
||||
- 访问:https://console.cloud.tencent.com/ses/address
|
||||
- 检查 `noreply@vionow.com` 的状态
|
||||
- 检查 `newletter@vionow.com` 的状态
|
||||
- 如果状态为"未验证"或"验证失败":
|
||||
|
||||
**验证步骤:**
|
||||
1. 进入SES控制台 → "发信地址"
|
||||
2. 点击"创建发信地址"或编辑现有地址
|
||||
3. 输入邮箱:`noreply@vionow.com`
|
||||
3. 输入邮箱:`newletter@vionow.com`
|
||||
4. 腾讯云会发送验证邮件到该邮箱
|
||||
5. 点击邮件中的验证链接完成验证
|
||||
6. 确认状态变为"已验证"
|
||||
@@ -73,39 +73,19 @@
|
||||
|
||||
---
|
||||
|
||||
### 3. 邮件模板配置 ⚠️ **生产环境必需**
|
||||
### 3. 邮件模板配置 ✅ **已配置**
|
||||
|
||||
**当前状态:**
|
||||
- `template-id=0` - 开发模式
|
||||
- `template-id=154360` - 生产模式(已配置)
|
||||
|
||||
**开发模式特点:**
|
||||
- ✅ 不会实际发送邮件
|
||||
- ✅ 验证码在日志中显示
|
||||
- ✅ 适合本地测试
|
||||
**当前配置:**
|
||||
- ✅ 模板ID已配置为 `154360`
|
||||
- ✅ 系统将使用生产模式,实际发送邮件
|
||||
|
||||
**生产环境需要:**
|
||||
- [ ] **创建邮件模板**
|
||||
|
||||
**创建步骤:**
|
||||
1. 访问:https://console.cloud.tencent.com/ses/template
|
||||
2. 点击"创建模板"
|
||||
3. 选择模板类型(触发邮件或批量邮件)
|
||||
4. 填写模板内容,例如:
|
||||
```
|
||||
您的AIGC平台验证码是:{{code}}
|
||||
验证码有效期5分钟,请勿泄露给他人。
|
||||
如果不是您本人操作,请忽略此邮件。
|
||||
```
|
||||
5. 使用 `{{code}}` 作为验证码变量(必须使用这个变量名)
|
||||
6. 提交审核
|
||||
7. 等待审核通过(通常需要1-2个工作日)
|
||||
8. 获取模板ID(例如:`12345`)
|
||||
|
||||
**更新配置:**
|
||||
```properties
|
||||
# 将开发模式改为生产模式
|
||||
tencent.ses.template-id=12345 # 替换为实际的模板ID
|
||||
```
|
||||
**模板说明:**
|
||||
- 模板ID: `154360`
|
||||
- 模式: 生产模式(会实际发送邮件)
|
||||
- 验证码变量: 模板中应包含 `{{code}}` 变量用于替换验证码
|
||||
|
||||
---
|
||||
|
||||
@@ -134,7 +114,7 @@ tencent.ses.template-id=${TENCENT_SES_TEMPLATE_ID}
|
||||
```bash
|
||||
export TENCENT_SES_SECRET_ID=你的SecretID
|
||||
export TENCENT_SES_SECRET_KEY=你的SecretKey
|
||||
export TENCENT_SES_FROM_EMAIL=noreply@vionow.com
|
||||
export TENCENT_SES_FROM_EMAIL=newletter@vionow.com
|
||||
export TENCENT_SES_TEMPLATE_ID=你的模板ID
|
||||
```
|
||||
|
||||
@@ -176,18 +156,18 @@ export TENCENT_SES_TEMPLATE_ID=你的模板ID
|
||||
-d '{"email":"test@example.com"}'
|
||||
```
|
||||
|
||||
- [ ] **查看日志**
|
||||
- 应该看到:"开发模式:邮件验证码发送到: test@example.com, 验证码: 123456"
|
||||
- 记录验证码用于登录测试
|
||||
- [ ] **检查邮箱**
|
||||
- 应该收到实际邮件,包含6位数字验证码
|
||||
- 邮件来自:newletter@vionow.com
|
||||
|
||||
- [ ] **测试登录**
|
||||
- 访问登录页面
|
||||
- 输入邮箱和验证码
|
||||
- 验证登录功能
|
||||
|
||||
**生产模式测试:**
|
||||
- [ ] **更新template-id配置**
|
||||
- [ ] **重启服务**
|
||||
**生产模式测试(已完成配置):**
|
||||
- [x] ✅ **Template-id已配置为154360**
|
||||
- [ ] **重启服务**(如果服务正在运行)
|
||||
- [ ] **发送测试邮件**
|
||||
- [ ] **检查实际邮箱是否收到邮件**
|
||||
|
||||
@@ -203,10 +183,8 @@ export TENCENT_SES_TEMPLATE_ID=你的模板ID
|
||||
### 🟡 重要(建议配置)
|
||||
4. **SES服务权限检查** - 确保账号有权限访问SES服务
|
||||
5. **SES服务开通和额度** - 确保有可用配额
|
||||
6. **测试验证** - 确保功能正常
|
||||
|
||||
### 🟢 可选(开发环境)
|
||||
7. **开发模式** - 当前已配置,可直接使用
|
||||
6. **测试验证** - 确保功能正常(会实际发送邮件)
|
||||
7. **发信地址验证** - 确保 newletter@vionow.com 已验证
|
||||
|
||||
---
|
||||
|
||||
@@ -219,9 +197,9 @@ export TENCENT_SES_TEMPLATE_ID=你的模板ID
|
||||
| SecretID | ✅ 已配置 | 需确认有效性和权限 |
|
||||
| SecretKey | ✅ 已配置 | 需确认有效性 |
|
||||
| Region | ✅ 已配置 | ap-beijing |
|
||||
| From-email | ✅ 已配置 | noreply@vionow.com(需确认已验证) |
|
||||
| From-email | ✅ 已配置 | newletter@vionow.com(需确认已验证) |
|
||||
| From-name | ✅ 已配置 | AIGC平台 |
|
||||
| Template-id | ⚠️ 开发模式 | 当前为0,生产环境需配置实际ID |
|
||||
| Template-id | ✅ 已配置 | 154360(生产模式) |
|
||||
|
||||
### 生产环境配置状态
|
||||
|
||||
@@ -276,8 +254,11 @@ curl -X POST http://localhost:8080/api/auth/login/email \
|
||||
|
||||
## 六、常见问题
|
||||
|
||||
### Q1: 开发模式下收不到邮件?
|
||||
**A:** 这是正常的!开发模式(template-id=0)不会实际发送邮件,验证码会在日志中显示。
|
||||
### Q1: 当前配置为生产模式
|
||||
**A:** 当前模板ID已配置为154360(生产模式),系统会实际发送邮件。请确保:
|
||||
- 发信地址 `newletter@vionow.com` 已验证
|
||||
- SES服务有可用额度
|
||||
- 模板ID 154360 在腾讯云SES控制台已审核通过
|
||||
|
||||
### Q2: 发送失败 - 认证错误
|
||||
```
|
||||
@@ -306,40 +287,27 @@ ResourceNotFound.TemplateNotFound
|
||||
- 检查模板是否已审核通过
|
||||
- 确认模板区域与配置的region一致
|
||||
|
||||
### Q5: 如何切换到生产模式?
|
||||
**A:**
|
||||
1. 验证发信地址
|
||||
2. 创建邮件模板并获取模板ID
|
||||
3. 更新 `tencent.ses.template-id` 配置
|
||||
4. 重启服务
|
||||
5. 测试实际发送邮件
|
||||
### Q5: 当前已是生产模式
|
||||
**A:** 当前已配置为生产模式(template-id=154360),系统会实际发送邮件。如需切换回开发模式,将template-id设置为0即可。
|
||||
|
||||
---
|
||||
|
||||
## 七、下一步操作建议
|
||||
|
||||
### 立即可做(开发测试)
|
||||
1. ✅ **保持当前配置**(开发模式)
|
||||
2. ✅ **启动服务测试登录功能**
|
||||
3. ✅ **使用日志中的验证码进行测试**
|
||||
### 当前配置(生产模式)
|
||||
1. ✅ **模板ID已配置为154360**(生产模式)
|
||||
2. ⚠️ **验证发信地址**(重要)
|
||||
- 确保 `newletter@vionow.com` 在SES控制台已验证
|
||||
- 访问:https://console.cloud.tencent.com/ses/address
|
||||
|
||||
### 生产环境准备(如需要)
|
||||
1. ⚠️ **验证发信地址**
|
||||
- 在SES控制台验证 `noreply@vionow.com`
|
||||
3. ⚠️ **测试实际发送邮件**
|
||||
- 重启服务(如果正在运行)
|
||||
- 发送测试验证码
|
||||
- 检查邮箱是否收到邮件
|
||||
|
||||
2. ⚠️ **创建邮件模板**
|
||||
- 创建验证码邮件模板
|
||||
- 等待审核通过
|
||||
- 获取模板ID
|
||||
|
||||
3. ⚠️ **更新生产环境配置**
|
||||
- 在 `application-prod.properties` 中添加SES配置
|
||||
- 设置环境变量
|
||||
|
||||
4. ⚠️ **测试生产模式**
|
||||
- 更新template-id配置
|
||||
- 重启服务
|
||||
- 测试实际发送邮件
|
||||
4. ⚠️ **更新生产环境配置**
|
||||
- 在 `application-prod.properties` 中已添加SES配置
|
||||
- 设置环境变量 `TENCENT_SES_TEMPLATE_ID=154360`
|
||||
|
||||
---
|
||||
|
||||
@@ -358,22 +326,23 @@ ResourceNotFound.TemplateNotFound
|
||||
## 九、总结
|
||||
|
||||
### 当前状态
|
||||
- ✅ **开发环境配置已完成**,可以直接启动测试
|
||||
- ✅ **开发模式已启用**(template-id=0),不会实际发送邮件
|
||||
- ⚠️ **生产环境配置缺失**,需要添加SES配置
|
||||
- ✅ **开发环境配置已完成**,包括模板ID 154360
|
||||
- ✅ **生产模式已启用**(template-id=154360),会实际发送邮件
|
||||
- ⚠️ **需要确保发信地址已验证**
|
||||
|
||||
### 最小启动要求(开发模式)
|
||||
### 最小启动要求
|
||||
1. ✅ SecretID和SecretKey(已配置)
|
||||
2. ✅ From-email地址(已配置)
|
||||
3. ✅ Template-id=0(开发模式,已配置)
|
||||
2. ✅ From-email地址(已配置:newletter@vionow.com)
|
||||
3. ✅ Template-id=154360(生产模式,已配置)
|
||||
|
||||
### 生产环境要求
|
||||
1. ⚠️ 已验证的发信地址
|
||||
2. ⚠️ 已审核通过的邮件模板
|
||||
3. ⚠️ 生产环境配置文件中的SES配置
|
||||
4. ⚠️ 有效的SecretID/SecretKey和SES服务权限
|
||||
1. ⚠️ 已验证的发信地址(newletter@vionow.com)
|
||||
2. ✅ 已配置的邮件模板(ID: 154360)
|
||||
3. ✅ 生产环境配置文件中的SES配置(已添加)
|
||||
4. ⚠️ 有效的SecretID/SecretKey和SES服务权限(需确认)
|
||||
|
||||
**当前可以:** 直接在开发模式下启动并测试登录功能(验证码在日志中显示)
|
||||
|
||||
**如需实际发送邮件:** 需要完成上述生产环境配置项
|
||||
**当前状态:** 已配置为生产模式,会实际发送邮件。请确保:
|
||||
- 发信地址 `newletter@vionow.com` 已验证
|
||||
- 模板ID 154360 已审核通过
|
||||
- SES服务有可用额度
|
||||
|
||||
|
||||
378
demo/EMAIL_LOGIN_TEST_CHECKLIST.md
Normal file
378
demo/EMAIL_LOGIN_TEST_CHECKLIST.md
Normal file
@@ -0,0 +1,378 @@
|
||||
# 邮件登录模块测试检查清单
|
||||
|
||||
## 📋 测试前检查
|
||||
|
||||
### 1. 配置检查 ✅
|
||||
|
||||
**当前配置状态:**
|
||||
- ✅ SecretID: `AKIDXw8HBtNfjdJm480xljV4QZUDi05wa0DE`
|
||||
- ✅ SecretKey: `tZyHMDsKadS4ScZhhU3PYUErGUVIqBIB`
|
||||
- ✅ Region: `ap-beijing`
|
||||
- ✅ From-email: `newletter@vionow.com`
|
||||
- ✅ Template-id: `154360`(生产模式)
|
||||
|
||||
**需要确认:**
|
||||
- [ ] **发信地址是否已验证**
|
||||
- 访问:https://console.cloud.tencent.com/ses/address
|
||||
- 检查 `newletter@vionow.com` 状态应为"已验证"
|
||||
- ⚠️ **重要**:未验证的发信地址无法发送邮件
|
||||
|
||||
- [ ] **模板ID是否有效**
|
||||
- 访问:https://console.cloud.tencent.com/ses/template
|
||||
- 检查模板ID `154360` 是否已审核通过
|
||||
- 确认模板中包含 `{{code}}` 变量
|
||||
|
||||
- [ ] **SES服务是否有可用额度**
|
||||
- 访问:https://console.cloud.tencent.com/ses
|
||||
- 检查账户余额或免费额度
|
||||
|
||||
---
|
||||
|
||||
### 2. 服务检查
|
||||
|
||||
- [ ] **后端服务是否运行**
|
||||
```bash
|
||||
# 检查服务是否在运行
|
||||
# 访问:http://localhost:8080
|
||||
```
|
||||
|
||||
- [ ] **前端服务是否运行**
|
||||
```bash
|
||||
# 检查前端是否在运行
|
||||
# 访问:http://localhost:5173
|
||||
```
|
||||
|
||||
- [ ] **数据库是否正常**
|
||||
- 确认数据库连接正常
|
||||
- 确认用户表等表结构存在
|
||||
|
||||
---
|
||||
|
||||
### 3. 测试邮箱准备
|
||||
|
||||
- [ ] **准备测试邮箱地址**
|
||||
- 使用真实的邮箱地址(可以正常接收邮件)
|
||||
- 建议使用常用邮箱:Gmail、QQ邮箱、163邮箱等
|
||||
- 确保可以访问邮箱查看验证码
|
||||
|
||||
---
|
||||
|
||||
## 🚀 测试步骤
|
||||
|
||||
### 步骤1:访问登录页面
|
||||
|
||||
1. 打开浏览器访问:`http://localhost:5173/login`
|
||||
- 或访问部署的前端地址
|
||||
|
||||
2. 确认页面显示:
|
||||
- ✅ 邮箱输入框
|
||||
- ✅ 验证码输入框
|
||||
- ✅ "获取验证码"按钮
|
||||
- ✅ "登录/注册"按钮
|
||||
|
||||
---
|
||||
|
||||
### 步骤2:发送验证码
|
||||
|
||||
1. **输入邮箱地址**
|
||||
- 输入一个有效的邮箱地址(例如:`test@example.com`)
|
||||
|
||||
2. **点击"获取验证码"按钮**
|
||||
- 观察按钮是否进入60秒倒计时状态
|
||||
- 观察是否有成功提示
|
||||
|
||||
3. **检查结果:**
|
||||
- ✅ **成功**:显示"验证码已发送到您的邮箱"
|
||||
- ❌ **失败**:检查错误信息
|
||||
|
||||
4. **查看日志(如有错误)**
|
||||
```bash
|
||||
# 查看后端日志,查找错误信息
|
||||
# 可能的问题:
|
||||
# - 发信地址未验证
|
||||
# - 模板ID无效
|
||||
# - 权限不足
|
||||
# - 额度不足
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 步骤3:接收验证码
|
||||
|
||||
**当前配置为生产模式(template-id=154360),会实际发送邮件。**
|
||||
|
||||
1. **检查邮箱收件箱**
|
||||
- 邮件来自:`newletter@vionow.com`
|
||||
- 邮件主题:根据模板配置
|
||||
- 邮件内容:包含6位数字验证码
|
||||
|
||||
2. **如果未收到邮件:**
|
||||
- 检查垃圾邮件文件夹
|
||||
- 等待1-2分钟(邮件发送可能有延迟)
|
||||
- 检查邮箱是否正确输入
|
||||
- 查看后端日志是否有错误
|
||||
|
||||
---
|
||||
|
||||
### 步骤4:输入验证码并登录
|
||||
|
||||
1. **输入验证码**
|
||||
- 输入邮箱中收到的6位数字验证码
|
||||
|
||||
2. **点击"登录/注册"按钮**
|
||||
|
||||
3. **检查结果:**
|
||||
- ✅ **成功**:
|
||||
- 跳转到主页或个人中心
|
||||
- 显示登录成功提示
|
||||
- 浏览器控制台中保存了token
|
||||
- ❌ **失败**:检查错误信息
|
||||
- 验证码错误
|
||||
- 验证码过期(5分钟)
|
||||
- 其他错误
|
||||
|
||||
---
|
||||
|
||||
### 步骤5:验证登录状态
|
||||
|
||||
1. **检查Token是否保存**
|
||||
- 打开浏览器开发者工具
|
||||
- 查看 `sessionStorage` 或 `localStorage`
|
||||
- 确认 `token` 和 `user` 信息已保存
|
||||
|
||||
2. **检查用户信息**
|
||||
- 查看个人中心或用户信息页面
|
||||
- 确认邮箱等信息正确显示
|
||||
|
||||
3. **测试自动注册功能**
|
||||
- 使用一个新的邮箱地址测试
|
||||
- 系统应自动创建新用户并登录
|
||||
|
||||
---
|
||||
|
||||
## 🔍 常见问题排查
|
||||
|
||||
### 问题1:点击获取验证码后没有反应
|
||||
|
||||
**可能原因:**
|
||||
- 前端服务未启动
|
||||
- 后端服务未启动
|
||||
- 网络连接问题
|
||||
|
||||
**解决方法:**
|
||||
1. 检查前端控制台错误信息
|
||||
2. 检查后端服务是否运行
|
||||
3. 检查API接口地址是否正确
|
||||
|
||||
---
|
||||
|
||||
### 问题2:显示"发送失败"或错误信息
|
||||
|
||||
**可能原因:**
|
||||
- 发信地址未验证
|
||||
- 模板ID无效或未审核
|
||||
- SecretID/SecretKey权限不足
|
||||
- SES服务额度不足
|
||||
|
||||
**解决方法:**
|
||||
1. 检查SES控制台发信地址状态
|
||||
2. 检查模板ID是否正确且已审核
|
||||
3. 检查API密钥权限
|
||||
4. 检查SES服务额度
|
||||
|
||||
**查看后端日志:**
|
||||
```bash
|
||||
# 查看详细的错误信息
|
||||
# 常见错误:
|
||||
# - InvalidParameter.EmailAddressNotVerified(发信地址未验证)
|
||||
# - ResourceNotFound.TemplateNotFound(模板不存在)
|
||||
# - InvalidSecretId.InvalidSignature(密钥错误)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 问题3:收不到邮件
|
||||
|
||||
**可能原因:**
|
||||
- 邮箱地址输入错误
|
||||
- 邮件被垃圾邮件过滤器拦截
|
||||
- 邮件发送延迟
|
||||
- 发信地址未验证(生产模式)
|
||||
|
||||
**解决方法:**
|
||||
1. 检查邮箱地址是否正确
|
||||
2. 检查垃圾邮件文件夹
|
||||
3. 等待1-2分钟
|
||||
4. 确认发信地址已验证
|
||||
5. 查看后端日志确认是否发送成功
|
||||
|
||||
---
|
||||
|
||||
### 问题4:验证码验证失败
|
||||
|
||||
**可能原因:**
|
||||
- 验证码输入错误
|
||||
- 验证码已过期(5分钟)
|
||||
- 验证码已被使用
|
||||
- 邮箱地址不匹配
|
||||
|
||||
**解决方法:**
|
||||
1. 确认验证码输入正确(6位数字)
|
||||
2. 确认在5分钟内使用
|
||||
3. 重新获取验证码
|
||||
4. 确认邮箱地址与获取验证码时一致
|
||||
|
||||
---
|
||||
|
||||
## 🧪 测试用例
|
||||
|
||||
### 测试用例1:正常登录流程
|
||||
|
||||
**步骤:**
|
||||
1. 输入邮箱:`test@example.com`
|
||||
2. 点击"获取验证码"
|
||||
3. 等待邮件到达(生产模式)
|
||||
4. 输入验证码
|
||||
5. 点击"登录/注册"
|
||||
|
||||
**预期结果:**
|
||||
- ✅ 验证码发送成功
|
||||
- ✅ 收到邮件
|
||||
- ✅ 登录成功
|
||||
- ✅ 跳转到主页
|
||||
|
||||
---
|
||||
|
||||
### 测试用例2:自动注册新用户
|
||||
|
||||
**步骤:**
|
||||
1. 输入一个从未使用过的邮箱:`newuser@example.com`
|
||||
2. 点击"获取验证码"
|
||||
3. 收到验证码后输入
|
||||
4. 点击"登录/注册"
|
||||
|
||||
**预期结果:**
|
||||
- ✅ 系统自动创建新用户
|
||||
- ✅ 自动登录
|
||||
- ✅ 用户信息正确保存
|
||||
|
||||
---
|
||||
|
||||
### 测试用例3:验证码过期测试
|
||||
|
||||
**步骤:**
|
||||
1. 获取验证码
|
||||
2. 等待超过5分钟
|
||||
3. 输入验证码尝试登录
|
||||
|
||||
**预期结果:**
|
||||
- ❌ 提示验证码已过期
|
||||
- ✅ 需要重新获取验证码
|
||||
|
||||
---
|
||||
|
||||
### 测试用例4:发送频率限制
|
||||
|
||||
**步骤:**
|
||||
1. 点击"获取验证码"
|
||||
2. 在60秒内再次点击"获取验证码"
|
||||
|
||||
**预期结果:**
|
||||
- ✅ 按钮处于倒计时状态,无法点击
|
||||
- ✅ 或提示"发送过于频繁"
|
||||
|
||||
---
|
||||
|
||||
### 测试用例5:邮箱格式验证
|
||||
|
||||
**步骤:**
|
||||
1. 输入无效邮箱:`invalid-email`
|
||||
2. 点击"获取验证码"
|
||||
|
||||
**预期结果:**
|
||||
- ❌ 提示"请输入正确的邮箱地址"
|
||||
|
||||
---
|
||||
|
||||
## ✅ 测试完成检查清单
|
||||
|
||||
完成测试后,确认以下功能正常:
|
||||
|
||||
- [ ] ✅ 可以发送验证码
|
||||
- [ ] ✅ 可以收到邮件(生产模式)
|
||||
- [ ] ✅ 可以输入验证码登录
|
||||
- [ ] ✅ 新用户可以自动注册
|
||||
- [ ] ✅ Token正确保存
|
||||
- [ ] ✅ 用户信息正确显示
|
||||
- [ ] ✅ 验证码过期机制正常
|
||||
- [ ] ✅ 发送频率限制正常
|
||||
- [ ] ✅ 邮箱格式验证正常
|
||||
|
||||
---
|
||||
|
||||
## 📝 测试记录模板
|
||||
|
||||
```
|
||||
测试时间:____年__月__日 __:__
|
||||
测试环境:开发/生产
|
||||
发信地址状态:已验证/未验证
|
||||
模板ID状态:已审核/未审核
|
||||
|
||||
测试邮箱:_______________
|
||||
测试结果:
|
||||
[ ] 发送验证码成功
|
||||
[ ] 收到邮件
|
||||
[ ] 登录成功
|
||||
[ ] 自动注册成功
|
||||
|
||||
遇到的问题:
|
||||
_________________________________
|
||||
|
||||
解决方案:
|
||||
_________________________________
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚨 重要提醒
|
||||
|
||||
### 生产模式注意事项
|
||||
|
||||
**当前配置为生产模式(template-id=154360),会实际发送邮件。**
|
||||
|
||||
⚠️ **必须确保:**
|
||||
1. 发信地址 `newletter@vionow.com` 已验证
|
||||
2. 模板ID `154360` 已审核通过
|
||||
3. SES服务有可用额度
|
||||
4. API密钥有SES服务权限
|
||||
|
||||
### 如果发信地址未验证
|
||||
|
||||
**临时解决方案(仅用于测试):**
|
||||
可以将 `template-id` 临时改为 `0`,进入开发模式:
|
||||
```properties
|
||||
tencent.ses.template-id=0
|
||||
```
|
||||
开发模式下不会实际发送邮件,验证码会在日志中显示。
|
||||
|
||||
---
|
||||
|
||||
## 🔗 相关资源
|
||||
|
||||
- **腾讯云SES控制台**: https://console.cloud.tencent.com/ses
|
||||
- **发信地址管理**: https://console.cloud.tencent.com/ses/address
|
||||
- **邮件模板管理**: https://console.cloud.tencent.com/ses/template
|
||||
- **邮箱验证登录指南**: `EMAIL_VERIFICATION_LOGIN_GUIDE.md`
|
||||
- **邮件登录配置清单**: `EMAIL_LOGIN_CONFIGURATION_CHECKLIST.md`
|
||||
|
||||
---
|
||||
|
||||
## ✅ 测试准备完成
|
||||
|
||||
**配置状态:**
|
||||
- ✅ 所有必需配置已设置
|
||||
- ⚠️ 需要确认发信地址已验证
|
||||
- ⚠️ 需要确认模板ID已审核
|
||||
|
||||
**可以开始测试!**
|
||||
|
||||
206
demo/EMAIL_SEND_TROUBLESHOOTING.md
Normal file
206
demo/EMAIL_SEND_TROUBLESHOOTING.md
Normal file
@@ -0,0 +1,206 @@
|
||||
# 邮件发送问题诊断指南
|
||||
|
||||
## 🔍 问题分析
|
||||
|
||||
根据你提供的日志,发现了以下情况:
|
||||
|
||||
### 日志分析
|
||||
|
||||
**你的日志显示:**
|
||||
```
|
||||
INFO ... VerificationCodeService : 邮件验证码发送成功,邮箱: 984523799@qq.com
|
||||
```
|
||||
|
||||
**但是缺少以下关键日志:**
|
||||
- ❌ 没有看到 "当前邮件模板ID配置: xxx"
|
||||
- ❌ 没有看到 "未配置邮件模板ID,使用开发模式"(开发模式警告)
|
||||
- ❌ 没有看到 "使用生产模式发送邮件"(生产模式日志)
|
||||
- ❌ 没有看到 "开始发送邮件,收件人: ..."(TencentSesMailService日志)
|
||||
|
||||
### 可能的原因
|
||||
|
||||
1. **配置值未正确读取**
|
||||
- `template-id=154360` 可能没有被正确读取
|
||||
- 默认值 `0` 被使用,进入了开发模式
|
||||
- 但开发模式的警告日志也没有出现
|
||||
|
||||
2. **服务使用旧版本代码**
|
||||
- 可能运行的jar包是旧版本
|
||||
- 需要重新编译并启动
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ 诊断步骤
|
||||
|
||||
### 步骤1:检查配置是否正确读取
|
||||
|
||||
我已经更新了代码,添加了更详细的日志。请:
|
||||
|
||||
1. **重新编译项目**
|
||||
```bash
|
||||
cd demo
|
||||
mvn clean package
|
||||
```
|
||||
|
||||
2. **重新启动服务**
|
||||
```bash
|
||||
java -jar target/demo-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev
|
||||
```
|
||||
|
||||
3. **再次测试发送验证码**
|
||||
|
||||
4. **查看新的日志输出**,应该能看到:
|
||||
```
|
||||
INFO ... VerificationCodeService : 当前邮件模板ID配置: 154360
|
||||
INFO ... VerificationCodeService : 使用生产模式发送邮件,收件人: xxx@qq.com, 模板ID: 154360
|
||||
INFO ... TencentSesMailService : 开始发送邮件,收件人: xxx@qq.com, 主题: 验证码, 模板ID: 154360
|
||||
```
|
||||
|
||||
### 步骤2:检查配置文件
|
||||
|
||||
确认 `application-dev.properties` 中的配置:
|
||||
|
||||
```properties
|
||||
tencent.ses.template-id=154360
|
||||
```
|
||||
|
||||
**注意:**
|
||||
- 确保没有空格
|
||||
- 确保值是正确的数字
|
||||
- 确保配置文件被正确加载(使用 `--spring.profiles.active=dev`)
|
||||
|
||||
### 步骤3:检查日志输出
|
||||
|
||||
**如果看到:**
|
||||
```
|
||||
INFO 当前邮件模板ID配置: 0
|
||||
WARN 未配置邮件模板ID,使用开发模式
|
||||
```
|
||||
|
||||
**说明:** 配置值没有正确读取,使用的是默认值0。
|
||||
|
||||
**解决方案:**
|
||||
1. 检查配置文件路径
|
||||
2. 确认使用的是dev配置:`--spring.profiles.active=dev`
|
||||
3. 检查配置文件名是否正确
|
||||
|
||||
**如果看到:**
|
||||
```
|
||||
INFO 当前邮件模板ID配置: 154360
|
||||
INFO 使用生产模式发送邮件,收件人: xxx@qq.com, 模板ID: 154360
|
||||
INFO 开始发送邮件,收件人: xxx@qq.com, 主题: 验证码, 模板ID: 154360
|
||||
ERROR 邮件验证码发送失败,邮箱: xxx@qq.com
|
||||
```
|
||||
|
||||
**说明:** 配置正确,但邮件发送失败。
|
||||
|
||||
**常见错误:**
|
||||
|
||||
1. **发信地址未验证**
|
||||
```
|
||||
InvalidParameter.EmailAddressNotVerified
|
||||
```
|
||||
**解决:** 在腾讯云SES控制台验证 `newletter@vionow.com`
|
||||
|
||||
2. **模板ID不存在或未审核**
|
||||
```
|
||||
ResourceNotFound.TemplateNotFound
|
||||
```
|
||||
**解决:** 确认模板ID 154360 已审核通过
|
||||
|
||||
3. **权限不足**
|
||||
```
|
||||
InvalidSecretId.InvalidSignature
|
||||
```
|
||||
**解决:** 检查SecretID/SecretKey是否正确,是否有SES服务权限
|
||||
|
||||
4. **额度不足**
|
||||
```
|
||||
余额不足
|
||||
```
|
||||
**解决:** 充值或检查免费额度
|
||||
|
||||
---
|
||||
|
||||
## 🚀 快速测试方案
|
||||
|
||||
### 方案1:临时使用开发模式测试
|
||||
|
||||
如果发信地址未验证或需要快速测试登录功能,可以临时切换到开发模式:
|
||||
|
||||
1. **修改配置文件**
|
||||
```properties
|
||||
tencent.ses.template-id=0
|
||||
```
|
||||
|
||||
2. **重新编译并启动**
|
||||
```bash
|
||||
mvn clean package
|
||||
java -jar target/demo-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev
|
||||
```
|
||||
|
||||
3. **测试发送验证码**
|
||||
- 会看到日志:`开发模式:邮件验证码发送到: xxx@qq.com, 验证码: 123456`
|
||||
- 从日志中获取验证码用于登录测试
|
||||
|
||||
### 方案2:检查SES配置状态
|
||||
|
||||
1. **访问SES控制台**
|
||||
- 发信地址管理:https://console.cloud.tencent.com/ses/address
|
||||
- 邮件模板管理:https://console.cloud.tencent.com/ses/template
|
||||
|
||||
2. **确认以下状态:**
|
||||
- [ ] `newletter@vionow.com` 状态为"已验证"
|
||||
- [ ] 模板ID `154360` 状态为"已审核"
|
||||
- [ ] SES服务有可用额度
|
||||
|
||||
---
|
||||
|
||||
## 📝 诊断检查清单
|
||||
|
||||
请按照以下顺序检查:
|
||||
|
||||
- [ ] **1. 配置检查**
|
||||
- 配置文件 `application-dev.properties` 中存在 `tencent.ses.template-id=154360`
|
||||
- 没有多余空格或特殊字符
|
||||
|
||||
- [ ] **2. 编译检查**
|
||||
- 执行了 `mvn clean package`
|
||||
- 编译成功,没有错误
|
||||
|
||||
- [ ] **3. 启动检查**
|
||||
- 使用 `--spring.profiles.active=dev` 启动
|
||||
- 启动日志中没有配置相关的错误
|
||||
|
||||
- [ ] **4. 日志检查**
|
||||
- 重新启动后,测试发送验证码
|
||||
- 查看日志中是否有新的详细信息
|
||||
|
||||
- [ ] **5. SES配置检查**
|
||||
- 发信地址已验证
|
||||
- 模板ID已审核
|
||||
- 有可用额度
|
||||
|
||||
---
|
||||
|
||||
## 🔧 下一步操作
|
||||
|
||||
1. **立即执行:**
|
||||
```bash
|
||||
cd demo
|
||||
mvn clean package
|
||||
java -jar target/demo-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev
|
||||
```
|
||||
|
||||
2. **再次测试发送验证码**
|
||||
|
||||
3. **查看新的日志输出**,告诉我你看到了什么日志信息
|
||||
|
||||
4. **根据新的日志信息,我可以进一步帮你诊断问题**
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 重要提示
|
||||
|
||||
**当前代码已更新,添加了更详细的日志输出。请重新编译并启动服务,然后再次测试。新的日志会帮助我们准确定位问题。**
|
||||
|
||||
112
demo/SES_TROUBLESHOOTING_GUIDE.md
Normal file
112
demo/SES_TROUBLESHOOTING_GUIDE.md
Normal file
@@ -0,0 +1,112 @@
|
||||
# 腾讯云SES邮件发送问题排查指南
|
||||
|
||||
## 当前错误
|
||||
|
||||
```
|
||||
错误码: FailedOperation.SendEmailErr
|
||||
错误信息: 操作失败。您的发送遇到问题,请检查Region参数是否指定准确,若Region参数无误,请联系腾讯云提交工单沟通原因并解决。
|
||||
```
|
||||
|
||||
## 问题诊断
|
||||
|
||||
这个错误通常表示以下问题之一:
|
||||
|
||||
### 1. **发信地址未验证** ⚠️ 最常见
|
||||
- 发信地址 `newletter@vionow.com` 可能未在腾讯云SES控制台的 **广州区域** 验证
|
||||
- 需要在对应区域验证发信地址或域名
|
||||
|
||||
### 2. **模板ID不存在或区域不匹配**
|
||||
- 模板ID `154360` 可能不存在于广州区域
|
||||
- 模板可能在其他区域创建,需要确认模板所在区域
|
||||
|
||||
### 3. **区域配置不匹配**
|
||||
- 当前配置区域:`ap-guangzhou`(广州)
|
||||
- 需要确保腾讯云控制台选择的地域与代码配置一致
|
||||
|
||||
## 解决步骤
|
||||
|
||||
### 步骤1: 登录腾讯云SES控制台
|
||||
|
||||
访问:https://console.cloud.tencent.com/ses
|
||||
|
||||
### 步骤2: 确认选择的地域
|
||||
|
||||
1. 在控制台右上角,确认当前选择的地域是否为 **"广州"**(ap-guangzhou)
|
||||
2. 如果选择了其他地域,切换到广州区域
|
||||
|
||||
### 步骤3: 验证发信地址
|
||||
|
||||
1. 进入 **"发信地址"** 或 **"身份验证"** 页面
|
||||
2. 检查 `newletter@vionow.com` 是否已添加并验证通过
|
||||
3. 如果未添加:
|
||||
- 点击 **"添加发信地址"**
|
||||
- 输入 `newletter@vionow.com`
|
||||
- 完成验证(通常会收到验证邮件)
|
||||
- 等待审核通过(通常几分钟到几小时)
|
||||
|
||||
### 步骤4: 检查模板ID
|
||||
|
||||
1. 进入 **"邮件模板"** 页面
|
||||
2. 确认模板ID `154360` 是否存在
|
||||
3. 确认模板状态为 **"已审核"** 或 **"已通过"**
|
||||
4. 如果模板不存在:
|
||||
- 检查模板是否在其他区域创建
|
||||
- 或者在当前区域重新创建模板
|
||||
- 获取新的模板ID并更新配置
|
||||
|
||||
### 步骤5: 检查账户状态
|
||||
|
||||
1. 确认SES服务已开通
|
||||
2. 检查账户是否有发送配额
|
||||
3. 检查是否有账户限制或黑名单
|
||||
|
||||
## 当前配置信息
|
||||
|
||||
根据您的配置文件:
|
||||
- **SecretID**: `AKIDoaEjFbqxxqZAcv8EE6oZCg2IQPG1fCxm`
|
||||
- **区域**: `ap-guangzhou`(广州)✅
|
||||
- **发信地址**: `newletter@vionow.com` ⚠️ 需要验证
|
||||
- **模板ID**: `154360` ⚠️ 需要确认存在
|
||||
|
||||
## 快速检查清单
|
||||
|
||||
- [ ] 在腾讯云SES控制台选择的地域是否为"广州"?
|
||||
- [ ] 发信地址 `newletter@vionow.com` 是否已在广州区域验证通过?
|
||||
- [ ] 模板ID `154360` 是否存在于广州区域?
|
||||
- [ ] 模板状态是否为"已审核"?
|
||||
- [ ] 账户是否有发送配额?
|
||||
- [ ] 访问密钥是否具有SES发送邮件权限?
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q: 发信地址验证需要多长时间?
|
||||
A: 通常几分钟到几小时,验证邮件会发送到邮箱地址的邮箱管理员处。
|
||||
|
||||
### Q: 如何验证域名而不是单个邮箱?
|
||||
A: 可以添加域名 `vionow.com` 进行验证,验证后该域名下所有邮箱都可以发信。
|
||||
|
||||
### Q: 模板在不同区域可以通用吗?
|
||||
A: 不可以,模板是区域隔离的,需要在使用的区域创建模板。
|
||||
|
||||
### Q: 如何查看模板的详细信息?
|
||||
A: 在SES控制台的"邮件模板"页面,点击模板ID查看详情,确认模板内容和状态。
|
||||
|
||||
## 如果仍然失败
|
||||
|
||||
如果完成以上步骤后仍然失败,请:
|
||||
|
||||
1. **检查腾讯云工单**:提交工单获取技术支持
|
||||
2. **查看详细日志**:检查应用日志中的完整错误堆栈
|
||||
3. **联系腾讯云客服**:通过控制台联系客服获取帮助
|
||||
|
||||
## 临时解决方案
|
||||
|
||||
如果需要快速测试,可以临时使用开发模式:
|
||||
|
||||
```properties
|
||||
# 在 application-dev.properties 中
|
||||
tencent.ses.template-id=0
|
||||
```
|
||||
|
||||
开发模式下不会发送真实邮件,验证码会记录在日志中。
|
||||
|
||||
104
demo/TENCENT_SES_PERMISSION_FIX.md
Normal file
104
demo/TENCENT_SES_PERMISSION_FIX.md
Normal file
@@ -0,0 +1,104 @@
|
||||
# 腾讯云SES权限配置指南
|
||||
|
||||
## 问题描述
|
||||
|
||||
当前错误:
|
||||
```
|
||||
AuthFailure.UnauthorizedOperation
|
||||
you are not authorized to perform operation (ses:SendEmail)
|
||||
resource (*) has no permission
|
||||
```
|
||||
|
||||
这个错误表示您的腾讯云访问密钥没有发送邮件的权限。
|
||||
|
||||
## 解决方案
|
||||
|
||||
### 方案1:在腾讯云控制台配置权限(推荐)
|
||||
|
||||
1. **登录腾讯云控制台**
|
||||
- 访问:https://console.cloud.tencent.com/
|
||||
|
||||
2. **进入访问管理(CAM)**
|
||||
- 在控制台顶部搜索"访问管理"或"CAM"
|
||||
- 或者直接访问:https://console.cloud.tencent.com/cam
|
||||
|
||||
3. **配置子账号权限**
|
||||
- 如果使用的是子账号密钥,需要为该子账号添加SES权限:
|
||||
- 进入"用户" → 找到对应用户 → 点击"授权"
|
||||
- 搜索"SES"或"邮件推送"
|
||||
- 添加策略:`QcloudSESFullAccess`(SES全读写访问权限)
|
||||
- 或者使用自定义策略,只授予`ses:SendEmail`权限
|
||||
|
||||
4. **如果使用主账号密钥**
|
||||
- 主账号默认拥有所有权限
|
||||
- 如果仍然报错,可能是密钥错误或已禁用
|
||||
- 检查:访问管理 → API密钥管理 → 查看密钥状态
|
||||
|
||||
5. **验证配置**
|
||||
- 权限配置后可能需要几分钟生效
|
||||
- 重新启动应用并测试
|
||||
|
||||
### 方案2:使用开发模式(临时方案)
|
||||
|
||||
如果您在开发环境测试,可以暂时使用开发模式:
|
||||
|
||||
1. **修改配置文件** `application-dev.properties`:
|
||||
```properties
|
||||
# 设置为0以使用开发模式(不发送真实邮件,仅在日志中记录验证码)
|
||||
tencent.ses.template-id=0
|
||||
```
|
||||
|
||||
2. **开发模式行为**
|
||||
- 不会调用腾讯云SES API
|
||||
- 验证码会记录在日志中
|
||||
- 可以直接使用日志中的验证码进行测试
|
||||
|
||||
### 方案3:创建自定义CAM策略(精细化权限)
|
||||
|
||||
如果您只想授予发送邮件权限,可以创建自定义策略:
|
||||
|
||||
1. **进入CAM策略管理**
|
||||
- 访问:https://console.cloud.tencent.com/cam/policy
|
||||
|
||||
2. **创建自定义策略**
|
||||
```json
|
||||
{
|
||||
"version": "2.0",
|
||||
"statement": [
|
||||
{
|
||||
"effect": "allow",
|
||||
"action": [
|
||||
"ses:SendEmail"
|
||||
],
|
||||
"resource": "*"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
3. **将策略绑定到子账号**
|
||||
- 进入"用户" → 找到对应用户 → 点击"授权"
|
||||
- 选择刚创建的自定义策略
|
||||
|
||||
## 当前配置信息
|
||||
|
||||
根据您的配置文件:
|
||||
- **SecretID**: `AKIDXw8HBtNfjdJm480xljV4QZUDi05wa0DE`
|
||||
- **区域**: `ap-beijing`
|
||||
- **发信地址**: `newletter@vionow.com`
|
||||
- **模板ID**: `154360`
|
||||
|
||||
## 检查清单
|
||||
|
||||
- [ ] 验证发信地址 `newletter@vionow.com` 已在腾讯云SES控制台验证通过
|
||||
- [ ] 验证模板ID `154360` 存在且已审核通过
|
||||
- [ ] 验证访问密钥所属账号具有SES发送邮件权限
|
||||
- [ ] 验证密钥未过期或被禁用
|
||||
- [ ] 等待权限配置生效(通常1-2分钟)
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [腾讯云SES权限说明](https://cloud.tencent.com/document/product/1288/45321)
|
||||
- [CAM策略语法](https://cloud.tencent.com/document/product/598/10603)
|
||||
- [发信地址验证指南](https://cloud.tencent.com/document/product/1288/68353)
|
||||
|
||||
@@ -370,6 +370,8 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from 'vue'
|
||||
@@ -517,6 +519,7 @@ const refreshStats = async () => {
|
||||
} finally {
|
||||
loadingStats.value = false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const performFullCleanup = async () => {
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
package com.example.demo.model;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EnumType;
|
||||
import jakarta.persistence.Enumerated;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
/**
|
||||
* 图生视频任务模型
|
||||
*/
|
||||
@@ -91,7 +99,9 @@ public class ImageToVideoTask {
|
||||
* 计算任务消耗积分
|
||||
*/
|
||||
private Integer calculateCost() {
|
||||
int actualDuration = (duration == null || duration <= 0) ? 5 : duration; // 使用默认时长但不修改字段
|
||||
// 安全处理duration可能为null的情况
|
||||
Integer safeDuration = duration;
|
||||
int actualDuration = (safeDuration == null || safeDuration <= 0) ? 5 : safeDuration; // 使用默认时长但不修改字段
|
||||
|
||||
int baseCost = 10; // 基础消耗
|
||||
int durationCost = actualDuration * 2; // 时长消耗
|
||||
|
||||
@@ -91,14 +91,24 @@ public class AlipayService {
|
||||
* 调用真实的支付宝API
|
||||
*/
|
||||
private Map<String, Object> callRealAlipayAPI(Payment payment) throws Exception {
|
||||
// 创建支付宝客户端,增加超时时间
|
||||
// 记录配置信息
|
||||
logger.info("=== 支付宝API配置信息 ===");
|
||||
logger.info("网关地址: {}", gatewayUrl);
|
||||
logger.info("应用ID: {}", appId);
|
||||
logger.info("字符集: {}", charset);
|
||||
logger.info("签名类型: {}", signType);
|
||||
logger.info("通知URL: {}", notifyUrl);
|
||||
logger.info("返回URL: {}", returnUrl);
|
||||
|
||||
// 设置连接和读取超时时间(60秒),需要在创建客户端之前设置
|
||||
System.setProperty("sun.net.client.defaultConnectTimeout", "60000");
|
||||
System.setProperty("sun.net.client.defaultReadTimeout", "60000");
|
||||
logger.info("超时配置: 连接超时=60秒, 读取超时=60秒");
|
||||
|
||||
// 创建支付宝客户端
|
||||
AlipayClient alipayClient = new DefaultAlipayClient(
|
||||
gatewayUrl, appId, privateKey, "json", charset, publicKey, signType);
|
||||
|
||||
// 设置连接和读取超时时间(30秒)
|
||||
System.setProperty("sun.net.client.defaultConnectTimeout", "30000");
|
||||
System.setProperty("sun.net.client.defaultReadTimeout", "30000");
|
||||
|
||||
// 使用预创建API生成二维码
|
||||
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
|
||||
request.setNotifyUrl(notifyUrl);
|
||||
@@ -127,10 +137,42 @@ public class AlipayService {
|
||||
break; // 成功则跳出循环
|
||||
} catch (Exception e) {
|
||||
retryCount++;
|
||||
logger.warn("支付宝API调用失败,第{}次重试,错误:{}", retryCount, e.getMessage());
|
||||
String errorType = e.getClass().getSimpleName();
|
||||
String errorMessage = e.getMessage();
|
||||
|
||||
logger.warn("支付宝API调用失败,第{}次重试", retryCount);
|
||||
logger.warn("错误类型: {}", errorType);
|
||||
logger.warn("错误信息: {}", errorMessage);
|
||||
|
||||
// 根据错误类型提供诊断建议
|
||||
if (errorMessage != null) {
|
||||
if (errorMessage.contains("Read timed out") || errorMessage.contains("timeout")) {
|
||||
logger.error("=== 网络超时错误诊断 ===");
|
||||
logger.error("可能的原因:");
|
||||
logger.error("1. 网络连接不稳定或延迟过高");
|
||||
logger.error("2. 支付宝沙箱环境响应慢(openapi.alipaydev.com)");
|
||||
logger.error("3. 防火墙或代理服务器阻止连接");
|
||||
logger.error("4. ngrok隧道可能已过期或不可用");
|
||||
logger.error("解决方案:");
|
||||
logger.error("1. 检查网络连接,尝试ping openapi.alipaydev.com");
|
||||
logger.error("2. 检查ngrok是否正常运行: {}", notifyUrl);
|
||||
logger.error("3. 考虑使用代理服务器或VPN");
|
||||
logger.error("4. 增加超时时间或重试次数");
|
||||
} else if (errorMessage.contains("Connection refused") || errorMessage.contains("ConnectException")) {
|
||||
logger.error("=== 连接拒绝错误诊断 ===");
|
||||
logger.error("无法连接到支付宝服务器: {}", gatewayUrl);
|
||||
logger.error("请检查网络连接和防火墙设置");
|
||||
} else if (errorMessage.contains("UnknownHostException")) {
|
||||
logger.error("=== DNS解析错误诊断 ===");
|
||||
logger.error("无法解析域名: {}", gatewayUrl);
|
||||
logger.error("请检查DNS设置和网络连接");
|
||||
}
|
||||
}
|
||||
|
||||
if (retryCount >= maxRetries) {
|
||||
logger.error("支付宝API调用失败,已达到最大重试次数");
|
||||
throw new RuntimeException("支付宝API调用失败:" + e.getMessage());
|
||||
logger.error("支付宝API调用失败,已达到最大重试次数({}次)", maxRetries);
|
||||
logger.error("最终失败原因: {}", errorMessage);
|
||||
throw new RuntimeException("支付宝API调用失败:" + errorMessage);
|
||||
}
|
||||
try {
|
||||
Thread.sleep(2000); // 等待2秒后重试
|
||||
|
||||
@@ -1,16 +1,5 @@
|
||||
package com.example.demo.service;
|
||||
|
||||
import com.example.demo.model.*;
|
||||
import com.example.demo.repository.OrderItemRepository;
|
||||
import com.example.demo.repository.OrderRepository;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
@@ -19,6 +8,22 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.example.demo.model.Order;
|
||||
import com.example.demo.model.OrderItem;
|
||||
import com.example.demo.model.OrderStatus;
|
||||
import com.example.demo.model.OrderType;
|
||||
import com.example.demo.model.User;
|
||||
import com.example.demo.repository.OrderItemRepository;
|
||||
import com.example.demo.repository.OrderRepository;
|
||||
|
||||
@Service
|
||||
@Transactional
|
||||
public class OrderService {
|
||||
@@ -164,6 +169,15 @@ public class OrderService {
|
||||
// 设置相应的时间戳
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
switch (newStatus) {
|
||||
case PENDING:
|
||||
// 待处理状态,不需要设置时间戳
|
||||
break;
|
||||
case CONFIRMED:
|
||||
// 已确认状态,不需要设置时间戳
|
||||
break;
|
||||
case PROCESSING:
|
||||
// 处理中状态,不需要设置时间戳
|
||||
break;
|
||||
case PAID:
|
||||
order.setPaidAt(now);
|
||||
break;
|
||||
@@ -179,6 +193,12 @@ public class OrderService {
|
||||
case CANCELLED:
|
||||
order.setCancelledAt(now);
|
||||
break;
|
||||
case REFUNDED:
|
||||
// 已退款状态,不需要设置时间戳
|
||||
break;
|
||||
default:
|
||||
// 其他状态,不需要设置时间戳
|
||||
break;
|
||||
}
|
||||
|
||||
Order updatedOrder = orderRepository.save(order);
|
||||
|
||||
@@ -38,7 +38,7 @@ public class TencentSesMailService {
|
||||
@Value("${tencent.ses.secret-key}")
|
||||
private String secretKey;
|
||||
|
||||
@Value("${tencent.ses.region:ap-beijing}")
|
||||
@Value("${tencent.ses.region:ap-hongkong}")
|
||||
private String region;
|
||||
|
||||
@Value("${tencent.ses.from-email}")
|
||||
@@ -109,8 +109,64 @@ public class TencentSesMailService {
|
||||
return true;
|
||||
|
||||
} catch (TencentCloudSDKException e) {
|
||||
logger.error("腾讯云SES API调用失败,收件人: {}, 错误码: {}, 错误信息: {}",
|
||||
toEmail, e.getErrorCode(), e.getMessage(), e);
|
||||
String errorCode = e.getErrorCode();
|
||||
String errorMessage = e.getMessage();
|
||||
|
||||
// 检查是否为权限错误
|
||||
if ("AuthFailure.UnauthorizedOperation".equals(errorCode) ||
|
||||
(errorMessage != null && errorMessage.contains("no permission"))) {
|
||||
logger.error("=== 腾讯云SES权限错误 ===");
|
||||
logger.error("收件人: {}", toEmail);
|
||||
logger.error("错误码: {}", errorCode);
|
||||
logger.error("错误信息: {}", errorMessage);
|
||||
logger.error("解决方案:");
|
||||
logger.error("1. 在腾讯云CAM中为访问密钥添加SES发送邮件权限");
|
||||
logger.error("2. 或临时使用开发模式:设置 tencent.ses.template-id=0");
|
||||
logger.error("详细配置指南请参考: TENCENT_SES_PERMISSION_FIX.md");
|
||||
}
|
||||
// 检查是否为区域不支持错误
|
||||
else if ("UnsupportedRegion".equals(errorCode) ||
|
||||
(errorMessage != null && errorMessage.contains("does not support this region"))) {
|
||||
logger.error("=== 腾讯云SES区域错误 ===");
|
||||
logger.error("收件人: {}", toEmail);
|
||||
logger.error("错误码: {}", errorCode);
|
||||
logger.error("错误信息: {}", errorMessage);
|
||||
logger.error("当前配置的区域: {}", region);
|
||||
logger.error("解决方案:");
|
||||
logger.error("1. 腾讯云SES通常支持以下区域:");
|
||||
logger.error(" - ap-hongkong (中国香港)");
|
||||
logger.error(" - ap-guangzhou (广州)");
|
||||
logger.error(" - ap-shanghai (上海)");
|
||||
logger.error(" - ap-nanjing (南京)");
|
||||
logger.error("2. 修改配置文件中的 tencent.ses.region 为支持的区域");
|
||||
logger.error("3. 当前配置:tencent.ses.region={}", region);
|
||||
}
|
||||
// 检查是否为发送失败错误
|
||||
else if ("FailedOperation.SendEmailErr".equals(errorCode) ||
|
||||
(errorMessage != null && errorMessage.contains("发送遇到问题"))) {
|
||||
logger.error("=== 腾讯云SES发送失败错误 ===");
|
||||
logger.error("收件人: {}", toEmail);
|
||||
logger.error("错误码: {}", errorCode);
|
||||
logger.error("错误信息: {}", errorMessage);
|
||||
logger.error("当前配置:");
|
||||
logger.error(" 区域: {}", region);
|
||||
logger.error(" 发信地址: {}", fromEmail);
|
||||
logger.error(" 模板ID: {}", templateId);
|
||||
logger.error("可能的原因:");
|
||||
logger.error("1. 发信地址 {} 未在腾讯云SES控制台的 {} 区域验证", fromEmail, region);
|
||||
logger.error("2. 模板ID {} 不存在于 {} 区域,或模板状态异常", templateId, region);
|
||||
logger.error("3. 发信地址已验证但未通过审核");
|
||||
logger.error("4. 账户可能未开通SES服务或服务受限");
|
||||
logger.error("解决方案:");
|
||||
logger.error("1. 登录腾讯云SES控制台: https://console.cloud.tencent.com/ses");
|
||||
logger.error("2. 确认选择的地域为: {}", region);
|
||||
logger.error("3. 检查发信地址 {} 是否已在该区域验证通过", fromEmail);
|
||||
logger.error("4. 检查模板ID {} 是否存在于该区域且状态为已审核", templateId);
|
||||
logger.error("5. 如未验证,请先验证发信地址或域名");
|
||||
} else {
|
||||
logger.error("腾讯云SES API调用失败,收件人: {}, 错误码: {}, 错误信息: {}",
|
||||
toEmail, errorCode, errorMessage, e);
|
||||
}
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
logger.error("发送邮件异常,收件人: {}", toEmail, e);
|
||||
|
||||
@@ -26,6 +26,19 @@ public class VerificationCodeService {
|
||||
@Value("${tencent.ses.template-id:0}")
|
||||
private Long templateId;
|
||||
|
||||
// 在构造函数中记录配置值,用于调试
|
||||
public VerificationCodeService() {
|
||||
// 构造函数用于初始化
|
||||
}
|
||||
|
||||
// 使用@PostConstruct确保在注入后记录配置
|
||||
@jakarta.annotation.PostConstruct
|
||||
public void init() {
|
||||
logger.info("=== 邮件服务配置初始化 ===");
|
||||
logger.info("模板ID配置值: {}", templateId);
|
||||
logger.info("如果为0或null,将使用开发模式");
|
||||
}
|
||||
|
||||
// 使用内存存储验证码
|
||||
private final ConcurrentHashMap<String, String> verificationCodes = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<String, Long> rateLimits = new ConcurrentHashMap<>();
|
||||
@@ -149,6 +162,9 @@ public class VerificationCodeService {
|
||||
*/
|
||||
private boolean sendEmail(String email, String code) {
|
||||
try {
|
||||
// 记录当前模板ID配置
|
||||
logger.info("当前邮件模板ID配置: {}", templateId);
|
||||
|
||||
// 如果没有配置模板ID,使用开发模式(仅记录日志)
|
||||
if (templateId == null || templateId == 0) {
|
||||
logger.warn("未配置邮件模板ID,使用开发模式。验证码: {}, 邮箱: {}", code, email);
|
||||
@@ -156,6 +172,8 @@ public class VerificationCodeService {
|
||||
return true; // 开发模式下返回成功
|
||||
}
|
||||
|
||||
logger.info("使用生产模式发送邮件,收件人: {}, 模板ID: {}", email, templateId);
|
||||
|
||||
// 使用腾讯云SES发送邮件
|
||||
boolean success = tencentSesMailService.sendVerificationCodeEmail(email, code, templateId);
|
||||
|
||||
@@ -163,12 +181,17 @@ public class VerificationCodeService {
|
||||
logger.info("邮件验证码发送成功,邮箱: {}", email);
|
||||
} else {
|
||||
logger.error("邮件验证码发送失败,邮箱: {}", email);
|
||||
logger.error("可能的原因:");
|
||||
logger.error("1. SES权限未配置(检查CAM权限策略)");
|
||||
logger.error("2. 发信地址未验证(检查SES控制台)");
|
||||
logger.error("3. 模板ID错误(当前模板ID: {})", templateId);
|
||||
logger.error("详细排查指南请参考: TENCENT_SES_PERMISSION_FIX.md");
|
||||
}
|
||||
|
||||
return success;
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("邮件发送异常,邮箱: {}", email, e);
|
||||
logger.error("邮件发送异常,邮箱: {}, 错误: {}", email, e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,14 +24,14 @@ jwt.expiration=86400000
|
||||
# 腾讯云SES配置
|
||||
# 主账号ID: 100040185043
|
||||
# 用户名: test
|
||||
tencent.ses.secret-id=AKIDXw8HBtNfjdJm480xljV4QZUDi05wa0DE
|
||||
tencent.ses.secret-key=tZyHMDsKadS4ScZhhU3PYUErGUVIqBIB
|
||||
tencent.ses.region=ap-beijing
|
||||
tencent.ses.from-email=noreply@vionow.com
|
||||
tencent.ses.secret-id=AKIDoaEjFbqxxqZAcv8EE6oZCg2IQPG1fCxm
|
||||
tencent.ses.secret-key=nR83I79FOSpGcqNo7JXkqnU8g7SjsxuG
|
||||
tencent.ses.region=ap-hongkong
|
||||
tencent.ses.from-email=newletter@vionow.com
|
||||
tencent.ses.from-name=AIGC平台
|
||||
# 邮件模板ID(在腾讯云SES控制台创建模板后获取)
|
||||
# 如果未配置或为0,将使用开发模式(仅记录日志)
|
||||
tencent.ses.template-id=0
|
||||
tencent.ses.template-id=154360
|
||||
|
||||
# AI API配置
|
||||
# 文生视频、图生视频、分镜视频都使用Comfly API
|
||||
|
||||
@@ -49,6 +49,16 @@ paypal.cancel-url=${PAYPAL_CANCEL_URL}
|
||||
jwt.secret=${JWT_SECRET}
|
||||
jwt.expiration=${JWT_EXPIRATION:604800000}
|
||||
|
||||
# 腾讯云SES配置 (生产环境)
|
||||
tencent.ses.secret-id=${TENCENT_SES_SECRET_ID}
|
||||
tencent.ses.secret-key=${TENCENT_SES_SECRET_KEY}
|
||||
tencent.ses.region=ap-hongkong
|
||||
tencent.ses.from-email=${TENCENT_SES_FROM_EMAIL}
|
||||
tencent.ses.from-name=AIGC平台
|
||||
# 邮件模板ID(在腾讯云SES控制台创建模板后获取)
|
||||
# 如果未配置或为0,将使用开发模式(仅记录日志)
|
||||
tencent.ses.template-id=${TENCENT_SES_TEMPLATE_ID}
|
||||
|
||||
# 生产环境日志配置
|
||||
logging.level.root=INFO
|
||||
logging.level.com.example.demo=INFO
|
||||
|
||||
Reference in New Issue
Block a user