fix: 转存时先查资源历史, 复用原账号; save_records加config_id

- 资源维度优先级 > IP维度: 先查share_url是否被转存过
- save_records 表新增 config_id 字段 + 写入时记录
- cloud.service.ts 所有 INSERT 写入 config.id
- credential.service.ts: getAndValidateCredential 加 shareUrl 参数
- 数据库 migration: config_id 到 save_records
This commit is contained in:
2026-05-15 06:45:48 +08:00
parent 58caaae37a
commit 329256bd33
3 changed files with 45 additions and 31 deletions

View File

@@ -423,11 +423,38 @@ export interface CredentialValidationResult {
*
* Reference: search-ucmao get_and_validate_credential() pattern.
*/
export async function getAndValidateCredential(cloudType: string, ipAddress?: string): Promise<CredentialValidationResult> {
export async function getAndValidateCredential(cloudType: string, ipAddress?: string, shareUrl?: string): Promise<CredentialValidationResult> {
const db = getDb();
let config: CloudConfig | undefined;
// ── Resource history lookup: if this share URL was saved before, reuse that account ──
if (shareUrl) {
const historyRecord = db.prepare(
`SELECT config_id, target_cloud, folder_name FROM save_records
WHERE share_url = ? AND target_cloud = ? AND status IN ('success', 'reused')
ORDER BY id DESC LIMIT 1`
).get(shareUrl, cloudType) as { config_id: number; target_cloud: string; folder_name: string } | undefined;
if (historyRecord) {
// Resource was previously saved — reuse the exact same config if still healthy
if (historyRecord.config_id) {
config = db.prepare(
`SELECT * FROM cloud_configs WHERE id = ? AND is_active = 1 AND consecutive_failures < 5`
).get(historyRecord.config_id) as CloudConfig | undefined;
}
if (!config) {
// Fallback: pick any healthy account from this cloud type
config = db.prepare(
`SELECT * FROM cloud_configs
WHERE cloud_type = ? AND is_active = 1 AND consecutive_failures < 5
ORDER BY is_primary DESC, last_used_at ASC NULLS FIRST
LIMIT 1`
).get(cloudType) as CloudConfig | undefined;
}
}
}
if (!ipAddress) {
// No IP info — fallback to simple LUR
config = db.prepare(