From e8ebd83d3c0811450362498fb0f987edd7b7fc12 Mon Sep 17 00:00:00 2001 From: hubian <908234780@qq.com> Date: Wed, 15 Apr 2026 16:26:13 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=B9=90=E8=A7=82=E9=94=81=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=8F=B7=E6=9C=BA=E5=88=B6=E8=A7=A3=E5=86=B3=E5=B9=B6?= =?UTF-8?q?=E5=8F=91=E7=BC=96=E8=BE=91=E5=86=B2=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 每条记录增加version字段,每次保存版本号递增 - 客户端保存时携带版本号,服务端检查是否一致 - 版本冲突时返回HTTP 409,包含服务端最新内容 - 前端显示冲突对话框,用户可选择放弃或强制覆盖 - 旧数据自动添加version=1 测试场景: - A和B同时加载版本1 - A保存成功 → 版本2 - B保存失败 → 409冲突 - B选择覆盖 → 版本3 --- app.py | 37 ++++++++-- templates/index.html | 163 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 194 insertions(+), 6 deletions(-) diff --git a/app.py b/app.py index bb86c96..1a6c86b 100644 --- a/app.py +++ b/app.py @@ -23,17 +23,23 @@ DATA_DIR = Path(__file__).parent / 'data' DATA_DIR.mkdir(exist_ok=True) NOTES_FILE = DATA_DIR / 'notes.json' -# 大模型配置 +# 大模型配置 (LLM Proxy) LLM_CONFIG = { - 'base_url': 'http://192.168.2.5:1234/v1', - 'api_key': 'sk-lm-fuP5tGU8:Hi7YU87jHyDP6Ay8Tl2j', - 'model': 'qwen3.5-4b', + 'base_url': 'http://192.168.2.17:19007/v1', + 'api_key': 'xxxx', + 'model': 'auto', } def load_notes(): """加载所有笔记""" if NOTES_FILE.exists(): notes = json.loads(NOTES_FILE.read_text(encoding='utf-8')) + + # 自动为旧数据添加版本号 + for note in notes: + if 'version' not in note: + note['version'] = 1 + # 按置顶和更新时间排序(置顶在前,更新时间降序) return sorted(notes, key=lambda x: (-int(x.get('pinned', False)), x.get('updated_at', '')), reverse=True) return [] @@ -132,6 +138,10 @@ def api_note_detail(note_id): if not note: return jsonify({'error': 'Note not found'}), 404 + # 确保有版本号 + if 'version' not in note: + note['version'] = 1 + return jsonify(note) @app.route('/api/notes', methods=['POST']) @@ -155,9 +165,10 @@ def api_create_note(): @app.route('/api/notes/', methods=['PUT']) def api_update_note(note_id): - """更新笔记内容""" + """更新笔记内容(带版本检查)""" data = request.get_json() content = data.get('content', '') + client_version = data.get('version', 0) # 客户端提交的版本号 notes = load_notes() note = next((n for n in notes if n['id'] == note_id), None) @@ -165,6 +176,21 @@ def api_update_note(note_id): if not note: return jsonify({'error': 'Note not found'}), 404 + # 确保服务端版本号存在 + server_version = note.get('version', 1) + + # 版本冲突检查:如果客户端版本 != 服务端版本,说明有并发编辑 + if client_version > 0 and client_version != server_version: + # 返回冲突响应,包含服务端最新内容 + return jsonify({ + 'error': 'version_conflict', + 'message': '该记录已被其他设备修改,请先查看最新内容', + 'server_version': server_version, + 'server_content': note.get('content', ''), + 'server_title': note.get('title', ''), + 'server_updated_at': note.get('updated_at', '') + }), 409 # HTTP 409 Conflict + now = datetime.now().strftime('%Y-%m-%d %H:%M:%S') # 新记录第一次输入内容时,自动生成标题 @@ -173,6 +199,7 @@ def api_update_note(note_id): note['content'] = content note['updated_at'] = now + note['version'] = server_version + 1 # 版本号递增 # 如果是新记录第一次输入内容,异步生成标题 if need_generate_title: diff --git a/templates/index.html b/templates/index.html index 6408d00..bddb744 100644 --- a/templates/index.html +++ b/templates/index.html @@ -4,6 +4,7 @@ 碎片记录 +