blob: 182a6e5ed48414bb6c18ce7f1436e1e117e6d6ab [file] [log] [blame]
TRM-coding29174c22025-06-18 23:56:51 +08001from flask import Flask, jsonify, request, session
2from flask_sqlalchemy import SQLAlchemy
3from flask_cors import CORS
22301069d1c06e62025-06-21 12:21:48 +08004from flask_jwt_extended import jwt_required, get_jwt_identity
TRM-coding29174c22025-06-18 23:56:51 +08005
6app = Flask(__name__)
7app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:123456@10.126.59.25/redbook'
8app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
9app.secret_key = 'your_secret_key'
10CORS(app, supports_credentials=True)
11
12db = SQLAlchemy(app)
13
14# 模型定义
15# 用户表
16class User(db.Model):
17 __tablename__ = 'users'
18 id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment='用户ID')
19 username = db.Column(db.String(50), unique=True, nullable=False, comment='用户名')
20 password = db.Column(db.String(255), nullable=False, comment='加密密码')
21 email = db.Column(db.String(100), unique=True, nullable=False, comment='邮箱')
22 avatar = db.Column(db.String(255), comment='头像URL')
23 role = db.Column(db.Enum('superadmin', 'user', 'admin'), default='user', comment='角色')
24 bio = db.Column(db.String(255), comment='个人简介')
25 status = db.Column(db.Enum('active', 'banned', 'muted'), default='active', comment='账号状态')
26 created_at = db.Column(db.TIMESTAMP, server_default=db.func.current_timestamp(), comment='创建时间')
27 updated_at = db.Column(db.TIMESTAMP, server_default=db.func.current_timestamp(),
28 onupdate=db.func.current_timestamp(), comment='更新时间')
29 birthday = db.Column(db.TIMESTAMP, server_default=db.func.current_timestamp(),comment='生日')
30 gender = db.Column(db.String(10),comment='性别')
31 location = db.Column(db.String(100),comment='所在地')
32
33 # 关系定义
34 posts = db.relationship('Post', backref='author', lazy=True)
35 behaviors = db.relationship('Behavior', backref='user', lazy=True)
36 comments = db.relationship('Comment', backref='commenter', lazy=True)
37 notifications = db.relationship('Notification', backref='recipient', lazy=True)
38 audits = db.relationship('Audit', backref='admin', lazy=True)
39 logs = db.relationship('Log', backref='logger', lazy=True)
40 user_tags = db.relationship('UserTag', backref='user', lazy=True)
41
42# 标签表
43class Tag(db.Model):
44 __tablename__ = 'tags'
45 id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment='标签ID')
46 name = db.Column(db.String(50), unique=True, nullable=False, comment='标签名称')
47 description = db.Column(db.String(255), comment='标签描述')
48 created_at = db.Column(db.TIMESTAMP, server_default=db.func.current_timestamp(), comment='创建时间')
49
50 # 关系定义
51 post_tags = db.relationship('PostTag', backref='tag', lazy=True)
52 user_tags = db.relationship('UserTag', backref='tag', lazy=True)
53
54# 话题/超话表
55class Topic(db.Model):
56 __tablename__ = 'topics'
57 id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment='话题ID')
58 name = db.Column(db.String(100), unique=True, nullable=False, comment='话题名称')
59 description = db.Column(db.Text, comment='话题描述')
60 status = db.Column(db.Enum('active', 'archived'), default='active', comment='状态')
61 created_at = db.Column(db.TIMESTAMP, server_default=db.func.current_timestamp(), comment='创建时间')
62
63 # 关系定义
64 posts = db.relationship('Post', backref='topic', lazy=True)
65
66# 内容帖子表
67class Post(db.Model):
68 __tablename__ = 'posts'
69 id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment='帖子ID')
70 user_id = db.Column(db.Integer, db.ForeignKey('users.id', ondelete='CASCADE'), nullable=False, comment='作者ID')
71 topic_id = db.Column(db.Integer, db.ForeignKey('topics.id', ondelete='SET NULL'), comment='所属话题ID')
72 type = db.Column(db.Enum('text', 'image', 'video', 'document'), default='text', comment='内容类型')
73 title = db.Column(db.String(255), nullable=False, comment='标题')
74 content = db.Column(db.Text, nullable=False, comment='正文内容')
75 media_urls = db.Column(db.JSON, comment='媒体资源URL数组')
76 status = db.Column(db.Enum('draft', 'pending', 'published', 'deleted', 'rejected'), default='draft', comment='状态')
77 heat = db.Column(db.Integer, default=0, comment='热度值')
78 created_at = db.Column(db.TIMESTAMP, server_default=db.func.current_timestamp(), comment='创建时间')
79 updated_at = db.Column(db.TIMESTAMP, server_default=db.func.current_timestamp(),
80 onupdate=db.func.current_timestamp(), comment='更新时间')
81
82 # 关系定义
83 behaviors = db.relationship('Behavior', backref='post', lazy=True)
84 comments = db.relationship('Comment', backref='post', lazy=True)
85 post_tags = db.relationship('PostTag', backref='post', lazy=True)
86 audits = db.relationship('Audit', backref='post', lazy=True)
87
88# 帖子标签关联表
89class PostTag(db.Model):
90 __tablename__ = 'post_tags'
91 post_id = db.Column(db.Integer, db.ForeignKey('posts.id', ondelete='CASCADE'), primary_key=True, comment='帖子ID')
92 tag_id = db.Column(db.Integer, db.ForeignKey('tags.id', ondelete='CASCADE'), primary_key=True, comment='标签ID')
93
94# 用户行为表
95class Behavior(db.Model):
96 __tablename__ = 'behaviors'
97 id = db.Column(db.BigInteger, primary_key=True, autoincrement=True, comment='行为ID')
98 user_id = db.Column(db.Integer, db.ForeignKey('users.id', ondelete='CASCADE'), nullable=False, comment='用户ID')
99 post_id = db.Column(db.Integer, db.ForeignKey('posts.id', ondelete='CASCADE'), nullable=False, comment='帖子ID')
100 type = db.Column(db.Enum('like', 'comment', 'favorite', 'view', 'share'), nullable=False, comment='行为类型')
101 value = db.Column(db.Integer, default=1, comment='行为值')
102 created_at = db.Column(db.TIMESTAMP, server_default=db.func.current_timestamp(), comment='行为时间')
103
104# 评论表
105class Comment(db.Model):
106 __tablename__ = 'comments'
107 id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment='评论ID')
108 post_id = db.Column(db.Integer, db.ForeignKey('posts.id', ondelete='CASCADE'), nullable=False, comment='帖子ID')
109 user_id = db.Column(db.Integer, db.ForeignKey('users.id', ondelete='CASCADE'), nullable=False, comment='用户ID')
110 parent_id = db.Column(db.Integer, db.ForeignKey('comments.id', ondelete='CASCADE'), comment='父评论ID')
111 content = db.Column(db.Text, nullable=False, comment='评论内容')
112 status = db.Column(db.Enum('active', 'deleted'), default='active', comment='状态')
113 created_at = db.Column(db.TIMESTAMP, server_default=db.func.current_timestamp(), comment='创建时间')
114 updated_at = db.Column(db.TIMESTAMP, server_default=db.func.current_timestamp(),
115 onupdate=db.func.current_timestamp(), comment='更新时间')
116
117 # 关系定义
118 replies = db.relationship('Comment', backref=db.backref('parent', remote_side=[id]), lazy=True)
119
120# 用户关注关系表
121class Follow(db.Model):
122 __tablename__ = 'follows'
123 follower_id = db.Column(db.Integer, db.ForeignKey('users.id', ondelete='CASCADE'), primary_key=True, comment='关注者ID')
124 followee_id = db.Column(db.Integer, db.ForeignKey('users.id', ondelete='CASCADE'), primary_key=True, comment='被关注者ID')
125 created_at = db.Column(db.TIMESTAMP, server_default=db.func.current_timestamp(), comment='关注时间')
126
127 # 关系定义
128 follower = db.relationship('User', foreign_keys=[follower_id], backref='following')
129 followee = db.relationship('User', foreign_keys=[followee_id], backref='followers')
130
131# 通知表
132class Notification(db.Model):
133 __tablename__ = 'notifications'
134 id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment='通知ID')
135 user_id = db.Column(db.Integer, db.ForeignKey('users.id', ondelete='CASCADE'), nullable=False, comment='接收用户ID')
136 type = db.Column(db.Enum('like', 'comment', 'follow', 'system', 'audit'), nullable=False, comment='通知类型')
137 content = db.Column(db.JSON, nullable=False, comment='通知内容')
138 is_read = db.Column(db.Boolean, default=False, comment='是否已读')
139 created_at = db.Column(db.TIMESTAMP, server_default=db.func.current_timestamp(), comment='创建时间')
140
141# 审核记录表
142class Audit(db.Model):
143 __tablename__ = 'audits'
144 id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment='审核ID')
145 post_id = db.Column(db.Integer, db.ForeignKey('posts.id', ondelete='CASCADE'), nullable=False, comment='帖子ID')
146 admin_id = db.Column(db.Integer, db.ForeignKey('users.id', ondelete='CASCADE'), nullable=False, comment='管理员ID')
147 result = db.Column(db.Enum('approved', 'rejected'), nullable=False, comment='审核结果')
148 reason = db.Column(db.String(255), comment='审核原因')
149 created_at = db.Column(db.TIMESTAMP, server_default=db.func.current_timestamp(), comment='审核时间')
150
151# 日志表
152class Log(db.Model):
153 __tablename__ = 'logs'
154 id = db.Column(db.BigInteger, primary_key=True, autoincrement=True, comment='日志ID')
155 user_id = db.Column(db.Integer, db.ForeignKey('users.id', ondelete='SET NULL'), comment='用户ID')
156 type = db.Column(db.Enum('access', 'error', 'behavior', 'system'), nullable=False, comment='日志类型')
157 content = db.Column(db.Text, nullable=False, comment='日志内容')
158 ip = db.Column(db.String(45), comment='IP地址')
159 created_at = db.Column(db.TIMESTAMP, server_default=db.func.current_timestamp(), comment='记录时间')
160
161# 用户兴趣标签表
162class UserTag(db.Model):
163 __tablename__ = 'user_tags'
164 user_id = db.Column(db.Integer, db.ForeignKey('users.id', ondelete='CASCADE'), primary_key=True, comment='用户ID')
165 tag_id = db.Column(db.Integer, db.ForeignKey('tags.id', ondelete='CASCADE'), primary_key=True, comment='标签ID')
166 weight = db.Column(db.Float, default=1.0, comment='兴趣权重')
167 created_at = db.Column(db.TIMESTAMP, server_default=db.func.current_timestamp(), comment='创建时间')
168 updated_at = db.Column(db.TIMESTAMP, server_default=db.func.current_timestamp(),
169 onupdate=db.func.current_timestamp(), comment='更新时间')
170
171
172# 自动登录用户11
173@app.before_request
174def auto_login():
175 # 如果用户未登录,自动设置为用户11
176 if 'user_id' not in session:
177 session['user_id'] = 11
178
179# 获取当前用户信息
180@app.route('/api/current-user')
181def current_user():
182 user_id = session.get('user_id', 1)
183 user = User.query.get(user_id)
184 if not user:
185 return jsonify({'error': 'User not found'}), 404
186
187 following_count = Follow.query.filter_by(follower_id=user_id).count()
188 followers_count = Follow.query.filter_by(followee_id=user_id).count()
189
190 return jsonify({
191 'id': user.id,
192 'username': user.username,
193 'email': user.email,
194 'avatar': user.avatar,
195 'bio': user.bio,
196 'following_count': following_count,
197 'followers_count': followers_count
198 })
199
200# 获取指定用户信息
201@app.route('/api/user/<int:user_id>')
202def get_user(user_id):
203 current_user_id = session.get('user_id', 1)
204 user = User.query.get(user_id)
205 if not user:
206 return jsonify({'error': 'User not found'}), 404
207
208 following_count = Follow.query.filter_by(follower_id=user_id).count()
209 followers_count = Follow.query.filter_by(followee_id=user_id).count()
210
211 is_following = False
212 if current_user_id:
213 is_following = Follow.query.filter_by(
214 follower_id=current_user_id,
215 followee_id=user_id
216 ).first() is not None
217
218 return jsonify({
219 'id': user.id,
220 'username': user.username,
221 'avatar': user.avatar,
222 'bio': user.bio,
223 'following_count': following_count,
224 'followers_count': followers_count,
225 'is_following': is_following,
226 'gender': user.gender,
227 'location': user.location,
228 'birthday': user.birthday
229 })
230
231# 更新用户信息
232@app.route('/api/user/<int:user_id>', methods=['PUT'])
233def update_user(user_id):
trma6b60ef2025-06-21 01:47:09 +0000234 # current_user_id = session.get('user_id', 1)
235 # if current_user_id != user_id:
236 # return jsonify({'error': 'Unauthorized'}), 403
TRM-coding29174c22025-06-18 23:56:51 +0800237
238 user = User.query.get(user_id)
239 if not user:
240 return jsonify({'error': 'User not found'}), 404
241
242 data = request.json
243 print(data)
244 if 'avatar' in data:
245 user.avatar = data['avatar']
246 if 'bio' in data:
247 user.bio = data['bio']
248 if 'gender' in data:
249 user.gender = data['gender']
250 if 'location' in data:
251 user.location = data['location']
252 if 'birthday' in data:
253 user.birthday = data['birthday']
254
255 db.session.commit()
256 return jsonify({
257 'id': user.id,
258 'avatar': user.avatar,
259 'bio': user.bio
260 })
261
262# 获取用户收藏
263@app.route('/api/user/<int:user_id>/favorites', methods=['GET'])
264def get_user_favorites(user_id):
265 # 检查用户是否登录
266 if 'user_id' not in session:
267 return jsonify({'error': '未登录'}), 401
268
trma6b60ef2025-06-21 01:47:09 +0000269 # # 验证请求的用户ID与登录用户ID是否一致
270 # if session['user_id'] != user_id:
271 # return jsonify({'error': '无权访问其他用户的收藏'}), 403
TRM-coding29174c22025-06-18 23:56:51 +0800272
273 try:
274 # 获取收藏行为及其关联的帖子
275 favorites = db.session.query(Behavior, Post).join(
276 Post, Behavior.post_id == Post.id
277 ).filter(
278 Behavior.user_id == user_id,
279 Behavior.type == 'favorite'
280 ).all()
281
282 # 构建响应数据
283 result = []
284 for behavior, post in favorites:
285 # 获取帖子作者信息
286 author = User.query.get(post.user_id)
287
288 # 构建响应对象
289 result.append({
290 'behavior_id': behavior.id,
291 'post': {
292 'id': post.id,
293 'title': post.title,
294 'type': post.type,
295 'content_preview': post.content[:100] + '...' if len(post.content) > 100 else post.content,
296 'media_urls': post.media_urls,
297 'created_at': post.created_at.strftime('%Y-%m-%d %H:%M:%S'),
298 'author': {
299 'id': author.id,
300 'username': author.username,
301 'avatar': author.avatar
302 }
303 },
304 'favorited_at': behavior.created_at.strftime('%Y-%m-%d %H:%M:%S')
305 })
306
307 return jsonify(result)
308
309 except Exception as e:
310 app.logger.error(f"获取收藏时出错: {str(e)}")
311 return jsonify({'error': '获取收藏失败'}), 500
312
313
314# 获取用户发布的帖子
315@app.route('/api/user/<int:user_id>/posts')
316def get_user_posts(user_id):
317 # 允许任何人查看用户发布的帖子
318 posts = Post.query.filter_by(
319 user_id=user_id,
320 status='published'
321 ).all()
322
323 return jsonify([{
324 'id': post.id,
325 'title': post.title,
326 'content': post.content[:100] + '...' if len(post.content) > 100 else post.content,
327 'type': post.type,
328 'heat': post.heat,
329 'created_at': post.created_at.strftime('%Y-%m-%d %H:%M')
330 } for post in posts])
331
332# 获取用户关注列表
333@app.route('/api/user/<int:user_id>/following')
334def get_user_following(user_id):
335 # 允许任何人查看用户的关注列表
336 following = Follow.query.filter_by(follower_id=user_id).all()
337
338 # 获取被关注用户的详细信息
339 following_list = []
340 for follow in following:
341 user = User.query.get(follow.followee_id)
342 if user:
343 followers_count = Follow.query.filter_by(followee_id=user.id).count()
344
345 following_list.append({
346 'id': user.id,
347 'username': user.username,
348 'avatar': user.avatar,
349 'followers_count': followers_count
350 })
351
352 return jsonify(following_list)
353
354# 关注/取消关注用户
22301069d1c06e62025-06-21 12:21:48 +0800355@app.route('/api/follow/<int:follower_id>/<int:followee_id>', methods=['POST', 'DELETE'])
356def follow_user(follower_id,followee_id):
357 # follower_id = session.get('user_id', 1)
358 print(follower_id)
TRM-coding29174c22025-06-18 23:56:51 +0800359 if follower_id == followee_id:
360 return jsonify({'error': 'Cannot follow yourself'}), 400
361
362 if request.method == 'POST':
363 existing = Follow.query.filter_by(
364 follower_id=follower_id,
365 followee_id=followee_id
366 ).first()
367
368 if not existing:
369 follow = Follow(
370 follower_id=follower_id,
371 followee_id=followee_id
372 )
373 db.session.add(follow)
374 db.session.commit()
375 return jsonify({'message': 'Followed successfully'})
376
377 elif request.method == 'DELETE':
378 follow = Follow.query.filter_by(
379 follower_id=follower_id,
380 followee_id=followee_id
381 ).first()
382
383 if follow:
384 db.session.delete(follow)
385 db.session.commit()
386 return jsonify({'message': 'Unfollowed successfully'})
387
388
389# 新增获取粉丝列表的API
390@app.route('/api/user/<int:user_id>/followers')
391def get_user_followers(user_id):
392 try:
393 # 查询关注该用户的用户列表
394 followers = db.session.query(User).join(
395 Follow, Follow.follower_id == User.id
396 ).filter(
397 Follow.followee_id == user_id
398 ).all()
399
400 # 获取当前登录用户ID(如果有)
401 current_user_id = session.get('user_id') if 'user_id' in session else None
402
403 # 构建响应数据
404 result = []
405 for user in followers:
406 # 检查当前用户是否关注了这个粉丝
407 is_following = False
408 if current_user_id:
409 follow_relation = Follow.query.filter_by(
410 follower_id=current_user_id,
411 followee_id=user.id
412 ).first()
413 is_following = follow_relation is not None
414
415 # 计算该粉丝的粉丝数
416 followers_count = Follow.query.filter_by(followee_id=user.id).count()
417
418 result.append({
419 'id': user.id,
420 'username': user.username,
421 'avatar': user.avatar,
422 'bio': user.bio,
423 'followers_count': followers_count,
424 'is_following': is_following
425 })
426
427
428 return jsonify({
429 'success': True,
430 'data': result
431 })
432
433 except Exception as e:
434 app.logger.error(f"获取粉丝列表失败: {str(e)}")
435 return jsonify({
436 'success': False,
437 'error': '获取粉丝列表失败'
438 }), 500
439
440# 辅助函数:检查当前用户是否关注了目标用户
441def check_following_status(follower_id, followee_id):
442 return Follow.query.filter_by(
443 follower_id=follower_id,
444 followee_id=followee_id
445 ).first() is not None
446
447
448# 记录用户点赞收藏总数
449@app.route('/api/user/<int:user_id>/interactions', methods=['GET'])
450def get_user_interactions(user_id):
451 try:
452 # 计算用户的获赞总数(所有帖子的点赞数)
453 like_count = db.session.query(db.func.sum(Behavior.value)).filter(
trma6b60ef2025-06-21 01:47:09 +0000454 Behavior.user_id==user_id,
TRM-coding29174c22025-06-18 23:56:51 +0800455 Behavior.type == 'like'
456 ).scalar() or 0
457
458 # 计算用户的收藏总数(所有帖子的收藏数)
459 favorite_count = db.session.query(db.func.sum(Behavior.value)).filter(
trma6b60ef2025-06-21 01:47:09 +0000460 Behavior.user_id==user_id,
TRM-coding29174c22025-06-18 23:56:51 +0800461 Behavior.type == 'favorite'
462 ).scalar() or 0
463
464 return jsonify({
465 'likes_count': like_count,
466 'favorites_count': favorite_count
467 })
468
469 except Exception as e:
470 app.logger.error(f"获取用户互动数据失败: {str(e)}")
471 return jsonify({'error': '获取互动数据失败'}), 500
472
22301069d1c06e62025-06-21 12:21:48 +0800473# 点赞/取消点赞路由 - 修改为包含用户ID
474@app.route('/api/users/<int:user_id>/posts/<int:post_id>/like', methods=['POST', 'DELETE'])
475def handle_like(user_id, post_id):
476 # 检查用户是否登录
477 if 'user_id' not in session:
478 return jsonify({'error': '未登录'}), 401
479
480 # 验证请求用户ID与登录用户ID是否一致
481 if session['user_id'] != user_id:
482 return jsonify({'error': '无权限操作'}), 403
483
484 post = Post.query.get(post_id)
485
486 if not post:
487 return jsonify({'error': '帖子不存在'}), 404
488
489 # 检查行为类型
490 behavior = Behavior.query.filter_by(
491 user_id=user_id,
492 post_id=post_id,
493 type='like'
494 ).first()
495
496 if request.method == 'POST':
497 # 点赞
498 if not behavior:
499 new_behavior = Behavior(
500 user_id=user_id,
501 post_id=post_id,
502 type='like',
503 value=1
504 )
505 db.session.add(new_behavior)
506 db.session.commit()
507 return jsonify({'message': '点赞成功', 'liked': True})
508 return jsonify({'message': '已点赞', 'liked': True})
509
510 elif request.method == 'DELETE':
511 # 取消点赞
512 if behavior:
513 db.session.delete(behavior)
514 db.session.commit()
515 return jsonify({'message': '已取消点赞', 'liked': False})
516 return jsonify({'message': '未点赞', 'liked': False})
517
518# 收藏/取消收藏路由 - 修改为包含用户ID
519@app.route('/api/users/<int:user_id>/posts/<int:post_id>/favorite', methods=['POST', 'DELETE'])
520def handle_favorite(user_id, post_id):
521 # 检查用户是否登录
522 if 'user_id' not in session:
523 return jsonify({'error': '未登录'}), 401
524
525 # 验证请求用户ID与登录用户ID是否一致
526 if session['user_id'] != user_id:
527 return jsonify({'error': '无权限操作'}), 403
528
529 post = Post.query.get(post_id)
530
531 if not post:
532 return jsonify({'error': '帖子不存在'}), 404
533
534 # 检查行为类型
535 behavior = Behavior.query.filter_by(
536 user_id=user_id,
537 post_id=post_id,
538 type='favorite'
539 ).first()
540
541 if request.method == 'POST':
542 # 收藏
543 if not behavior:
544 new_behavior = Behavior(
545 user_id=user_id,
546 post_id=post_id,
547 type='favorite',
548 value=1
549 )
550 db.session.add(new_behavior)
551 db.session.commit()
552 return jsonify({'message': '收藏成功', 'favorited': True})
553 return jsonify({'message': '已收藏', 'favorited': True})
554
555 elif request.method == 'DELETE':
556 # 取消收藏
557 if behavior:
558 db.session.delete(behavior)
559 db.session.commit()
560 return jsonify({'message': '已取消收藏', 'favorited': False})
561 return jsonify({'message': '未收藏', 'favorited': False})
562
563# 获取帖子互动状态(是否点赞/收藏) - 修改为包含用户ID
564@app.route('/api/users/<int:user_id>/posts/<int:post_id>/interaction-status')
565def get_post_interaction_status(user_id, post_id):
566 # 检查用户是否登录
567 if 'user_id' not in session:
568 return jsonify({
569 'liked': False,
570 'favorited': False
571 })
572
573 # 验证请求用户ID与登录用户ID是否一致
574 if session['user_id'] != user_id:
575 return jsonify({
576 'liked': False,
577 'favorited': False
578 })
579
580 liked = Behavior.query.filter_by(
581 user_id=user_id,
582 post_id=post_id,
583 type='like'
584 ).first() is not None
585
586 favorited = Behavior.query.filter_by(
587 user_id=user_id,
588 post_id=post_id,
589 type='favorite'
590 ).first() is not None
591
592 return jsonify({
593 'liked': liked,
594 'favorited': favorited
595 })
596
TRM-coding29174c22025-06-18 23:56:51 +0800597
598if __name__ == '__main__':
599 app.run(debug=True,port='5715',host='0.0.0.0')