mirror of
https://github.com/zhinianboke/xianyu-auto-reply.git
synced 2025-09-02 02:38:48 +08:00
修复bug
This commit is contained in:
parent
0aa1796764
commit
cf4f41b391
@ -1183,14 +1183,18 @@ class DBManager:
|
|||||||
"INSERT INTO keywords (cookie_id, keyword, reply, item_id, type) VALUES (?, ?, ?, ?, 'text')",
|
"INSERT INTO keywords (cookie_id, keyword, reply, item_id, type) VALUES (?, ?, ?, ?, 'text')",
|
||||||
(cookie_id, keyword, reply, normalized_item_id))
|
(cookie_id, keyword, reply, normalized_item_id))
|
||||||
except sqlite3.IntegrityError as ie:
|
except sqlite3.IntegrityError as ie:
|
||||||
# 如果遇到唯一约束冲突,记录详细错误信息
|
# 如果遇到唯一约束冲突,记录详细错误信息并回滚
|
||||||
item_desc = f"商品ID: {normalized_item_id}" if normalized_item_id else "通用关键词"
|
item_desc = f"商品ID: {normalized_item_id}" if normalized_item_id else "通用关键词"
|
||||||
logger.error(f"关键词唯一约束冲突: Cookie={cookie_id}, 关键词='{keyword}', {item_desc}")
|
logger.error(f"关键词唯一约束冲突: Cookie={cookie_id}, 关键词='{keyword}', {item_desc}")
|
||||||
|
self.conn.rollback()
|
||||||
raise ie
|
raise ie
|
||||||
|
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
logger.info(f"文本关键字保存成功: {cookie_id}, {len(keywords)}条,图片关键词已保留")
|
logger.info(f"文本关键字保存成功: {cookie_id}, {len(keywords)}条,图片关键词已保留")
|
||||||
return True
|
return True
|
||||||
|
except sqlite3.IntegrityError:
|
||||||
|
# 唯一约束冲突,重新抛出异常让上层处理
|
||||||
|
raise
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"文本关键字保存失败: {e}")
|
logger.error(f"文本关键字保存失败: {e}")
|
||||||
self.conn.rollback()
|
self.conn.rollback()
|
||||||
|
@ -1631,10 +1631,22 @@ def update_keywords_with_item_id(cid: str, body: KeywordWithItemIdIn, current_us
|
|||||||
|
|
||||||
keywords_to_save.append((keyword, reply, item_id))
|
keywords_to_save.append((keyword, reply, item_id))
|
||||||
|
|
||||||
# 保存关键词
|
# 保存关键词(只保存文本关键词,保留图片关键词)
|
||||||
success = db_manager.save_keywords_with_item_id(cid, keywords_to_save)
|
try:
|
||||||
if not success:
|
success = db_manager.save_text_keywords_only(cid, keywords_to_save)
|
||||||
raise HTTPException(status_code=500, detail="保存关键词失败")
|
if not success:
|
||||||
|
raise HTTPException(status_code=500, detail="保存关键词失败")
|
||||||
|
except Exception as e:
|
||||||
|
error_msg = str(e)
|
||||||
|
if "UNIQUE constraint failed" in error_msg:
|
||||||
|
# 解析具体的冲突信息
|
||||||
|
if "keywords.cookie_id, keywords.keyword" in error_msg:
|
||||||
|
raise HTTPException(status_code=400, detail="关键词重复!该关键词已存在(可能是图片关键词或文本关键词),请使用其他关键词")
|
||||||
|
else:
|
||||||
|
raise HTTPException(status_code=400, detail="关键词重复!请使用不同的关键词或商品ID组合")
|
||||||
|
else:
|
||||||
|
log_with_user('error', f"保存关键词时发生未知错误: {error_msg}", current_user)
|
||||||
|
raise HTTPException(status_code=500, detail="保存关键词失败")
|
||||||
|
|
||||||
log_with_user('info', f"更新Cookie关键字(含商品ID): {cid}, 数量: {len(keywords_to_save)}", current_user)
|
log_with_user('info', f"更新Cookie关键字(含商品ID): {cid}, 数量: {len(keywords_to_save)}", current_user)
|
||||||
return {"msg": "updated", "count": len(keywords_to_save)}
|
return {"msg": "updated", "count": len(keywords_to_save)}
|
||||||
|
100
static/js/app.js
100
static/js/app.js
@ -424,6 +424,42 @@ async function refreshAccountList() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 只刷新关键词列表(不重新加载商品列表等其他数据)
|
||||||
|
async function refreshKeywordsList() {
|
||||||
|
if (!currentCookieId) {
|
||||||
|
console.warn('没有选中的账号,无法刷新关键词列表');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${apiBase}/keywords-with-item-id/${currentCookieId}`, {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${authToken}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const data = await response.json();
|
||||||
|
console.log('刷新关键词列表,从服务器获取的数据:', data);
|
||||||
|
|
||||||
|
// 更新缓存数据
|
||||||
|
keywordsData[currentCookieId] = data;
|
||||||
|
|
||||||
|
// 只重新渲染关键词列表
|
||||||
|
renderKeywordsList(data);
|
||||||
|
|
||||||
|
// 清除关键词缓存
|
||||||
|
clearKeywordCache();
|
||||||
|
} else {
|
||||||
|
console.error('刷新关键词列表失败:', response.status);
|
||||||
|
showToast('刷新关键词列表失败', 'danger');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('刷新关键词列表失败:', error);
|
||||||
|
showToast('刷新关键词列表失败', 'danger');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 加载账号关键词
|
// 加载账号关键词
|
||||||
async function loadAccountKeywords() {
|
async function loadAccountKeywords() {
|
||||||
const accountId = document.getElementById('accountSelect').value;
|
const accountId = document.getElementById('accountSelect').value;
|
||||||
@ -588,22 +624,32 @@ async function addKeyword() {
|
|||||||
currentKeywords.splice(window.editingIndex, 1);
|
currentKeywords.splice(window.editingIndex, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 准备要保存的关键词列表
|
// 准备要保存的关键词列表(只包含文本类型的关键字)
|
||||||
let keywordsToSave = [...currentKeywords];
|
let textKeywords = currentKeywords.filter(item => (item.type || 'text') === 'text');
|
||||||
|
|
||||||
// 如果是编辑模式,先移除原关键词
|
// 如果是编辑模式,先移除原关键词
|
||||||
if (isEditMode && typeof window.editingIndex !== 'undefined') {
|
if (isEditMode && typeof window.editingIndex !== 'undefined') {
|
||||||
keywordsToSave.splice(window.editingIndex, 1);
|
// 需要重新计算在文本关键字中的索引
|
||||||
|
const originalKeyword = keywordsData[currentCookieId][window.editingIndex];
|
||||||
|
const textIndex = textKeywords.findIndex(item =>
|
||||||
|
item.keyword === originalKeyword.keyword &&
|
||||||
|
(item.item_id || '') === (originalKeyword.item_id || '')
|
||||||
|
);
|
||||||
|
if (textIndex !== -1) {
|
||||||
|
textKeywords.splice(textIndex, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查关键词是否已存在(考虑商品ID)
|
// 检查关键词是否已存在(考虑商品ID,检查所有类型的关键词)
|
||||||
const existingKeyword = keywordsToSave.find(item =>
|
const allKeywords = keywordsData[currentCookieId] || [];
|
||||||
|
const existingKeyword = allKeywords.find(item =>
|
||||||
item.keyword === keyword &&
|
item.keyword === keyword &&
|
||||||
(item.item_id || '') === (itemId || '')
|
(item.item_id || '') === (itemId || '')
|
||||||
);
|
);
|
||||||
if (existingKeyword) {
|
if (existingKeyword) {
|
||||||
const itemIdText = itemId ? `(商品ID: ${itemId})` : '(通用关键词)';
|
const itemIdText = itemId ? `(商品ID: ${itemId})` : '(通用关键词)';
|
||||||
showToast(`关键词 "${keyword}" ${itemIdText} 已存在,请使用其他关键词或商品ID`, 'warning');
|
const typeText = existingKeyword.type === 'image' ? '图片' : '文本';
|
||||||
|
showToast(`关键词 "${keyword}" ${itemIdText} 已存在(${typeText}关键词),请使用其他关键词或商品ID`, 'warning');
|
||||||
toggleLoading(false);
|
toggleLoading(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -614,7 +660,7 @@ async function addKeyword() {
|
|||||||
reply: reply,
|
reply: reply,
|
||||||
item_id: itemId || ''
|
item_id: itemId || ''
|
||||||
};
|
};
|
||||||
keywordsToSave.push(newKeyword);
|
textKeywords.push(newKeyword);
|
||||||
|
|
||||||
const response = await fetch(`${apiBase}/keywords-with-item-id/${currentCookieId}`, {
|
const response = await fetch(`${apiBase}/keywords-with-item-id/${currentCookieId}`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -623,7 +669,7 @@ async function addKeyword() {
|
|||||||
'Authorization': `Bearer ${authToken}`
|
'Authorization': `Bearer ${authToken}`
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
keywords: keywordsToSave
|
keywords: textKeywords
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -667,12 +713,26 @@ async function addKeyword() {
|
|||||||
keywordInput.focus();
|
keywordInput.focus();
|
||||||
}, 100);
|
}, 100);
|
||||||
|
|
||||||
loadAccountKeywords(); // 重新加载关键词列表
|
// 只刷新关键词列表,不重新加载整个界面
|
||||||
clearKeywordCache(); // 清除缓存
|
await refreshKeywordsList();
|
||||||
} else {
|
} else {
|
||||||
const errorText = await response.text();
|
try {
|
||||||
console.error('关键词添加失败:', errorText);
|
const errorData = await response.json();
|
||||||
showToast('关键词添加失败', 'danger');
|
const errorMessage = errorData.detail || '关键词添加失败';
|
||||||
|
console.error('关键词添加失败:', errorMessage);
|
||||||
|
|
||||||
|
// 检查是否是重复关键词的错误
|
||||||
|
if (errorMessage.includes('关键词已存在') || errorMessage.includes('关键词重复') || errorMessage.includes('UNIQUE constraint')) {
|
||||||
|
showToast(`❌ 关键词重复:${errorMessage}`, 'warning');
|
||||||
|
} else {
|
||||||
|
showToast(`❌ ${errorMessage}`, 'danger');
|
||||||
|
}
|
||||||
|
} catch (parseError) {
|
||||||
|
// 如果无法解析JSON,使用原始文本
|
||||||
|
const errorText = await response.text();
|
||||||
|
console.error('关键词添加失败:', errorText);
|
||||||
|
showToast('❌ 关键词添加失败', 'danger');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('添加关键词失败:', error);
|
console.error('添加关键词失败:', error);
|
||||||
@ -893,9 +953,8 @@ async function deleteKeyword(cookieId, index) {
|
|||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
showToast('关键词删除成功', 'success');
|
showToast('关键词删除成功', 'success');
|
||||||
// 重新加载关键词列表
|
// 只刷新关键词列表,不重新加载整个界面
|
||||||
loadAccountKeywords();
|
await refreshKeywordsList();
|
||||||
clearKeywordCache(); // 清除缓存
|
|
||||||
} else {
|
} else {
|
||||||
const errorText = await response.text();
|
const errorText = await response.text();
|
||||||
console.error('关键词删除失败:', errorText);
|
console.error('关键词删除失败:', errorText);
|
||||||
@ -6134,16 +6193,17 @@ async function addImageKeyword() {
|
|||||||
const modal = bootstrap.Modal.getInstance(document.getElementById('addImageKeywordModal'));
|
const modal = bootstrap.Modal.getInstance(document.getElementById('addImageKeywordModal'));
|
||||||
modal.hide();
|
modal.hide();
|
||||||
|
|
||||||
// 重新加载关键词列表
|
// 只刷新关键词列表,不重新加载整个界面
|
||||||
loadAccountKeywords();
|
await refreshKeywordsList();
|
||||||
clearKeywordCache();
|
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
const errorData = await response.json();
|
const errorData = await response.json();
|
||||||
let errorMessage = errorData.detail || '图片关键词添加失败';
|
let errorMessage = errorData.detail || '图片关键词添加失败';
|
||||||
|
|
||||||
// 根据不同的错误类型提供更友好的提示
|
// 根据不同的错误类型提供更友好的提示
|
||||||
if (errorMessage.includes('图片尺寸过大')) {
|
if (errorMessage.includes('关键词') && (errorMessage.includes('已存在') || errorMessage.includes('重复'))) {
|
||||||
|
errorMessage = `❌ 关键词重复:${errorMessage}`;
|
||||||
|
} else if (errorMessage.includes('图片尺寸过大')) {
|
||||||
errorMessage = '❌ 图片尺寸过大,请选择尺寸较小的图片(建议不超过4096x4096像素)';
|
errorMessage = '❌ 图片尺寸过大,请选择尺寸较小的图片(建议不超过4096x4096像素)';
|
||||||
} else if (errorMessage.includes('图片像素总数过大')) {
|
} else if (errorMessage.includes('图片像素总数过大')) {
|
||||||
errorMessage = '❌ 图片像素总数过大,请选择分辨率较低的图片';
|
errorMessage = '❌ 图片像素总数过大,请选择分辨率较低的图片';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user