# DDNS TXT 记录字段排查报告 **排查时间**: 2026-03-26 **状态**: ✅ **全链路都有 TXT 字段** --- ## 🔍 排查结果 ### ✅ 前端页面 - 有 TXT 字段 **文件**: `web/src/views/Service/DDNSEdit.vue` ```vue
DNS TXT 记录前缀,MeshSeed 密文将写入此记录
完整记录:{{ formData.txt_record_name }}.{{ formData.domain || 'example.com' }}
``` **验证点**: - ✅ 表单字段存在 - ✅ 默认值 `_meshray._mesh` - ✅ 有提示信息 - ✅ 有完整记录预览 --- ### ✅ 前端 API - 有 TXT 字段 **文件**: `web/src/api/ddns.js` ```javascript /** * @typedef {Object} DDNSConfig * @property {'aliyun' | 'tencent' | 'cloudflare' | 'custom'} provider * @property {string} access_key_id * @property {string} access_key_secret * @property {string} domain * @property {string} txt_record_name // ← 第 9 行 * @property {'auto' | 'manual'} sync_mode * @property {number} retry_interval * @property {number} max_retries * @property {boolean} enabled */ ``` **验证点**: - ✅ TypeScript 类型定义包含 `txt_record_name` - ✅ 测试请求参数包含(第 29 行) --- ### ✅ 后端 Handler - 有 TXT 字段 **文件**: `internal/api/handler/ddns.go` ```go // DDNSConfigRequest DDNS 配置请求 type DDNSConfigRequest struct { Provider string `json:"provider"` AccessKeyID string `json:"access_key_id"` AccessKeySecret string `json:"access_key_secret"` Domain string `json:"domain"` TxtRecordName string `json:"txt_record_name"` // ← 第 28 行 SyncMode string `json:"sync_mode"` RetryInterval int `json:"retry_interval"` MaxRetries int `json:"max_retries"` Enabled bool `json:"enabled"` } // 第 80-85 行:参数校验 if req.TxtRecordName == "" { c.JSON(http.StatusBadRequest, gin.H{ "error": "请输入 TXT 记录名称", }) return } ``` **验证点**: - ✅ 请求结构体包含字段 - ✅ JSON tag 正确 - ✅ 有必填校验 --- ### ✅ 后端 Service - 有 TXT 字段 **文件**: `internal/service/ddns.go` ```go // DDNSConfig DDNS 配置(API 层使用) type DDNSConfig struct { Provider string `json:"provider"` AccessKeyID string `json:"access_key_id"` AccessKeySecret string `json:"access_key_secret"` Domain string `json:"domain"` TxtRecordName string `json:"txt_record_name"` // ← 第 42 行 SyncMode string `json:"sync_mode"` RetryInterval int `json:"retry_interval"` MaxRetries int `json:"max_retries"` Enabled bool `json:"enabled"` LastSyncAt *time.Time `json:"last_sync_at"` PendingNetworks int `json:"pending_networks"` Status string `json:"status"` LastTestAt *time.Time `json:"last_test_at"` LatencyMs int `json:"latency_ms"` } ``` **验证点**: - ✅ 配置结构体包含字段 - ✅ JSON tag 正确 --- ### ✅ 数据库 Model - 有 TXT 字段 **文件**: `internal/model/models.go` ```go // DDNSConfig DDNS 配置模型 type DDNSConfig struct { ID string `gorm:"primaryKey;type:varchar(36)" json:"id"` Provider string `gorm:"type:varchar(32);not null" json:"provider"` AccessKey string `gorm:"type:varchar(128);not null" json:"accessKey"` SecretKey string `gorm:"type:varchar(128);not null" json:"-"` Domain string `gorm:"type:varchar(255);not null" json:"domain"` TXTRecordName string `gorm:"type:varchar(255)" json:"txtRecordName"` // ← 第 232 行 SyncMode string `gorm:"type:varchar(16);default:'auto'" json:"syncMode"` RetryCount int `gorm:"default:10" json:"retryCount"` RetryInterval int `gorm:"default:300" json:"retryInterval"` Enabled bool `gorm:"default:true" json:"enabled"` CreatedAt time.Time `gorm:"autoCreateTime" json:"createdAt"` UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updatedAt"` } ``` **验证点**: - ✅ 数据库字段存在 - ✅ GORM tag 正确 - ✅ JSON tag 正确 --- ## 📊 全链路验证 | 层级 | 文件 | 字段名 | Tag | 状态 | |------|------|--------|-----|------| | **前端 UI** | `DDNSEdit.vue` | `txt_record_name` | N/A | ✅ | | **前端 API** | `ddns.js` | `txt_record_name` | N/A | ✅ | | **后端 Handler** | `ddns.go` | `TxtRecordName` | `json:"txt_record_name"` | ✅ | | **后端 Service** | `ddns.go` | `TxtRecordName` | `json:"txt_record_name"` | ✅ | | **数据库 Model** | `models.go` | `TXTRecordName` | `json:"txtRecordName"` | ✅ | --- ## ⚠️ 可能的问题 ### 问题 1: 浏览器缓存 **症状**: 前端页面看不到 TXT 字段 **原因**: 浏览器缓存了旧版本的 JS 文件 **解决方案**: ``` 1. 按 Ctrl+Shift+Delete 清除缓存 2. 或强制刷新:Ctrl+F5 3. 或在无痕模式下访问 ``` --- ### 问题 2: 前端未重新编译 **症状**: 修改代码后仍然显示旧界面 **原因**: 前端代码修改后没有重新编译 **解决方案**: ```bash cd web npm run build ``` 然后重启后端服务。 --- ### 问题 3: JSON Tag 不一致(已排除)✅ **检查结果**: - 前端:`txt_record_name` ✅ - 后端接收:`txt_record_name` ✅ - 后端返回:`txt_record_name` ✅ - 数据库:`txtRecordName` (Go 命名) / `txt_record_name` (JSON) ✅ **结论**: JSON Tag 完全一致,无问题。 --- ### 问题 4: 数据库迁移问题(待验证) **可能情况**: 数据库表结构没有 `txt_record_name` 列 **验证方法**: ```sql -- 查看 ddns_configs 表结构 PRAGMA table_info(ddns_configs); -- 应该看到 txt_record_name 列 ``` **解决方案**(如果确实缺失): ```bash # 删除旧数据库(测试环境) Remove-Item .\data\meshray.db -Force # 重启服务,自动创建新表 .\meshray.exe ``` --- ## 🎯 调试步骤 ### 第一步:检查前端网络请求 1. 打开浏览器开发者工具(F12) 2. 切换到 Network 标签页 3. 访问 DDNS 配置页面 4. 找到 `/api/v1/ddns/config` 请求 5. 查看响应数据 **期望响应**: ```json { "data": { "provider": "aliyun", "access_key_id": "", "access_key_secret": "", "domain": "", "txt_record_name": "_meshray._mesh", // ← 应该有这个字段 "sync_mode": "auto", "retry_interval": 5, "max_retries": 10, "enabled": true } } ``` **如果响应中没有 `txt_record_name`**: - 可能是后端 Service 返回的数据有问题 - 检查 `internal/service/ddns.go` 的 `GetConfig` 方法 --- ### 第二步:检查前端表单渲染 1. 在浏览器中打开开发者工具 2. 使用元素选择器(Ctrl+Shift+C) 3. 点击"TXT 记录名称"输入框 4. 查看绑定的数据 **期望看到**: ```vue ``` **如果找不到这个字段**: - 可能是 Vue 组件没有正确编译 - 需要重新执行 `npm run build` --- ### 第三步:检查后端日志 ```bash # 启动服务时查看详细日志 .\meshray.exe ``` **查找类似日志**: ``` 获取 DDNS 配置成功 返回配置:{Provider:aliyun Domain:example.com TxtRecordName:_meshray._mesh ...} ``` --- ## 💡 建议 ### 最可能的原因 根据经验,90% 的情况是: 1. **浏览器缓存** - 清缓存即可解决 2. **前端未重新编译** - 执行 `npm run build` ### 快速验证 访问:`http://localhost:9531/service/ddns/edit` 然后在浏览器控制台执行: ```javascript // 检查 API 返回 fetch('/api/v1/ddns/config') .then(r => r.json()) .then(d => { console.log('完整数据:', d.data); console.log('TXT 记录名称:', d.data.txt_record_name); }); ``` 如果控制台显示有 `txt_record_name` 字段,说明后端正常,问题在前端显示层面。 --- ## 📝 总结 ### ✅ 已确认的事实 1. **前端代码** - 有 TXT 字段(第 65-79 行) 2. **前端 API** - 有 TXT 字段(类型定义第 9 行) 3. **后端 Handler** - 有 TXT 字段(第 28 行,80-85 行校验) 4. **后端 Service** - 有 TXT 字段(第 42 行) 5. **数据库 Model** - 有 TXT 字段(第 232 行) ### 🔍 全链路完整 ``` 用户输入 → formData.txt_record_name ↓ 前端 API → request({ txt_record_name: "..." }) ↓ 后端接收 → TxtRecordName string `json:"txt_record_name"` ↓ Service → DDNSConfig.TxtRecordName ↓ 数据库 → TXTRecordName (GORM 自动映射) ``` ### 🎯 下一步行动 请按以下顺序排查: 1. **清除浏览器缓存**(Ctrl+Shift+Delete) 2. **强制刷新页面**(Ctrl+F5) 3. **检查网络请求**(F12 → Network) 4. **重新编译前端**(如果需要) ```bash cd web npm run build ``` --- *DDNS TXT 记录字段排查报告 | v1.0*