feat: 空内容保存确认 + 重命名标题功能
This commit is contained in:
25
app.py
25
app.py
@@ -182,6 +182,31 @@ def api_update_note(note_id):
|
||||
|
||||
return jsonify(note)
|
||||
|
||||
|
||||
@app.route('/api/notes/<note_id>/rename', methods=['POST'])
|
||||
def api_rename_note(note_id):
|
||||
"""重命名笔记标题"""
|
||||
data = request.get_json()
|
||||
new_title = data.get('title', '').strip()
|
||||
|
||||
if not new_title:
|
||||
return jsonify({'error': '标题不能为空'}), 400
|
||||
|
||||
notes = load_notes()
|
||||
note = next((n for n in notes if n['id'] == note_id), None)
|
||||
|
||||
if not note:
|
||||
return jsonify({'error': 'Note not found'}), 404
|
||||
|
||||
note['title'] = new_title
|
||||
note['updated_at'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||
|
||||
# 重新排序
|
||||
notes = sorted(notes, key=lambda x: (not x.get('pinned', False), x.get('updated_at', '')), reverse=True)
|
||||
save_notes(notes)
|
||||
|
||||
return jsonify({'success': True, 'title': new_title, 'note': note})
|
||||
|
||||
@app.route('/api/notes/<note_id>/title', methods=['POST'])
|
||||
def api_regenerate_title(note_id):
|
||||
"""手动重新生成标题"""
|
||||
|
||||
@@ -151,6 +151,10 @@
|
||||
<i class="ri-more-fill"></i>
|
||||
</button>
|
||||
<div id="menu-${n.id}" class="hidden absolute right-0 top-full mt-1 bg-white rounded-lg shadow-lg border z-10 min-w-[100px]">
|
||||
<button onclick="event.stopPropagation(); renameTitle('${n.id}', '${n.title || '新记录'}'); hideMenu('${n.id}')"
|
||||
class="w-full px-3 py-2 text-left text-sm text-gray-600 hover:bg-gray-50 flex items-center gap-2">
|
||||
<i class="ri-edit-line"></i> 重命名
|
||||
</button>
|
||||
<button onclick="event.stopPropagation(); exportItem('${n.id}'); hideMenu('${n.id}')"
|
||||
class="w-full px-3 py-2 text-left text-sm text-gray-600 hover:bg-gray-50 flex items-center gap-2">
|
||||
<i class="ri-download-line"></i> 导出
|
||||
@@ -221,6 +225,19 @@
|
||||
saveTimer = setTimeout(async () => {
|
||||
const content = document.getElementById('editor').value;
|
||||
|
||||
// 检查内容是否为空(只有空白字符)
|
||||
if (content.trim() === '') {
|
||||
const oldContent = await fetch(`/api/notes/${currentNoteId}`).then(r => r.json()).then(n => n.content || '');
|
||||
// 如果原来有内容,现在变空了,需要确认
|
||||
if (oldContent.trim() !== '') {
|
||||
if (!confirm('内容已清空,确定要保存为空吗?\n(可能发生意外清空,请确认)')) {
|
||||
// 用户取消,恢复旧内容
|
||||
document.getElementById('editor').value = oldContent;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const res = await fetch(`/api/notes/${currentNoteId}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
@@ -346,6 +363,37 @@
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
|
||||
// 重命名标题
|
||||
async function renameTitle(id, currentTitle) {
|
||||
const newTitle = prompt('请输入新标题:', currentTitle);
|
||||
|
||||
if (newTitle === null) return; // 用户取消
|
||||
|
||||
const trimmedTitle = newTitle.trim();
|
||||
if (!trimmedTitle) {
|
||||
alert('标题不能为空!');
|
||||
return;
|
||||
}
|
||||
|
||||
const res = await fetch(`/api/notes/${id}/rename`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ title: trimmedTitle })
|
||||
});
|
||||
|
||||
const data = await res.json();
|
||||
|
||||
if (data.success) {
|
||||
// 如果是当前编辑的笔记,更新标题显示
|
||||
if (currentNoteId === id) {
|
||||
document.getElementById('titleText').textContent = data.title;
|
||||
}
|
||||
loadNotes();
|
||||
} else {
|
||||
alert(data.error || '重命名失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 显示/隐藏菜单
|
||||
function toggleMenu(id) {
|
||||
const menu = document.getElementById(`menu-${id}`);
|
||||
|
||||
Reference in New Issue
Block a user