合并JWL,WZY,TRM代码

Change-Id: Ifb4fcad3c06733e1e005e7d8d9403e3561010fb4
diff --git a/Merge/back_wzy/routes/posts.py b/Merge/back_wzy/routes/posts.py
new file mode 100644
index 0000000..e01bdd8
--- /dev/null
+++ b/Merge/back_wzy/routes/posts.py
@@ -0,0 +1,150 @@
+# routes/posts.py
+from flask import Blueprint, request, jsonify, abort
+from extensions    import db
+from models.post   import Post
+from models.behavior import Behavior
+
+posts_bp = Blueprint('posts', __name__)
+
+@posts_bp.route('', methods=['POST'])
+def create_post():
+    data = request.get_json() or {}
+    post = Post(**data)
+    db.session.add(post)
+    db.session.commit()
+    return jsonify({'id': post.id}), 201
+
+@posts_bp.route('', methods=['GET'])
+def list_posts():
+    posts = Post.query.filter_by(status='published').all()
+    return jsonify([{
+        'id': p.id,
+        'title': p.title,
+        'heat': p.heat,
+        'created_at': p.created_at.isoformat()
+    } for p in posts])
+
+@posts_bp.route('/<int:post_id>', methods=['GET'])
+def get_post(post_id):
+    post = Post.query.get_or_404(post_id)
+    return jsonify({
+        'id': post.id,
+        'user_id': post.user_id,
+        'title': post.title,
+        'content': post.content,
+        'media_urls': post.media_urls,
+        'status': post.status,
+        'heat': post.heat,
+        'created_at': post.created_at.isoformat(),
+        'updated_at': post.updated_at.isoformat()
+    })
+
+@posts_bp.route('/<int:post_id>', methods=['PUT'])
+def update_post(post_id):
+    """
+    修改帖子
+    URL 参数:
+      post_id - 要修改的帖子 ID
+    JSON Body 可选字段:
+      title       (string)
+      content     (string)
+      topic_id    (int)     — 必须是 topics 表中已有的 ID
+      media_urls  (list)    — 字符串数组
+      status      (string)  — 'draft','pending','published','deleted','rejected'
+    """
+    post = Post.query.get_or_404(post_id)
+    data = request.get_json() or {}
+    # 只更新客户端传来的字段
+    for key in ('title','content','topic_id','media_urls','status'):
+        if key in data:
+            setattr(post, key, data[key])
+    db.session.commit()
+    return '', 204
+
+@posts_bp.route('/<int:post_id>', methods=['DELETE'])
+def delete_post(post_id):
+    post = Post.query.get_or_404(post_id)
+    db.session.delete(post)
+    db.session.commit()
+    return '', 204
+
+
+@posts_bp.route('/<int:post_id>/<action>', methods=['POST'])
+def post_action(post_id, action):
+    """
+    支持的 action: like, favorite, view, share
+    对于 like 和 favorite,保证每个用户每帖只做一次。
+    """
+    if action not in ('like', 'favorite', 'view', 'share'):
+        abort(400, 'Invalid action')
+
+    data = request.get_json() or {}
+    user_id = data.get('user_id')
+    if not user_id:
+        abort(400, 'user_id required')
+
+    # 对 like/favorite 做去重检查
+    if action in ('like', 'favorite'):
+        exists = Behavior.query.filter_by(
+            user_id=user_id,
+            post_id=post_id,
+            type=action
+        ).first()
+        if exists:
+            return jsonify({'error': f'already {action}d'}), 400
+
+    # 创建行为记录
+    beh = Behavior(user_id=user_id, post_id=post_id, type=action)
+    db.session.add(beh)
+
+    # 更新热度
+    post = Post.query.get_or_404(post_id)
+    post.heat += 1
+
+    db.session.commit()
+    return '', 201
+
+
+# 取消点赞
+@posts_bp.route('/<int:post_id>/like', methods=['DELETE'])
+def unlike(post_id):
+    user_id = request.get_json(silent=True) and request.get_json().get('user_id')
+    if not user_id:
+        abort(400, 'user_id required')
+    # 查找已有的 like 行为
+    beh = Behavior.query.filter_by(
+        user_id=user_id,
+        post_id=post_id,
+        type='like'
+    ).first()
+    if not beh:
+        return jsonify({'error': 'not liked yet'}), 400
+
+    db.session.delete(beh)
+    # 更新热度,确保不降到负数
+    post = Post.query.get_or_404(post_id)
+    post.heat = max(post.heat - 1, 0)
+    db.session.commit()
+    return '', 204
+
+# 取消收藏
+@posts_bp.route('/<int:post_id>/favorite', methods=['DELETE'])
+def unfavorite(post_id):
+    user_id = request.get_json(silent=True) and request.get_json().get('user_id')
+    if not user_id:
+        abort(400, 'user_id required')
+    # 查找已有的 favorite 行为
+    beh = Behavior.query.filter_by(
+        user_id=user_id,
+        post_id=post_id,
+        type='favorite'
+    ).first()
+    if not beh:
+        return jsonify({'error': 'not favorited yet'}), 400
+
+    db.session.delete(beh)
+    # 更新热度
+    post = Post.query.get_or_404(post_id)
+    post.heat = max(post.heat - 1, 0)
+    db.session.commit()
+    return '', 204
\ No newline at end of file