button state
Change-Id: Ic152517cd68c4fe7d03e8e150fb7e13acf6842b9
diff --git a/Merge/back_rhj/__pycache__/config.cpython-312.pyc b/Merge/back_rhj/__pycache__/config.cpython-312.pyc
index 52dc95c..b52f5ec 100644
--- a/Merge/back_rhj/__pycache__/config.cpython-312.pyc
+++ b/Merge/back_rhj/__pycache__/config.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_rhj/app/__init__.py b/Merge/back_rhj/app/__init__.py
index 098898c..aa7050e 100644
--- a/Merge/back_rhj/app/__init__.py
+++ b/Merge/back_rhj/app/__init__.py
@@ -20,25 +20,25 @@
from .blueprints.recommend import recommend_bp
app.register_blueprint(recommend_bp)
- # Register scheduler blueprint
- from .blueprints.scheduler import scheduler_bp
- app.register_blueprint(scheduler_bp)
+ # # Register scheduler blueprint
+ # from .blueprints.scheduler import scheduler_bp
+ # app.register_blueprint(scheduler_bp)
- # 初始化定时任务管理器
- from .utils.scheduler_manager import SchedulerManager
+ # # 初始化定时任务管理器
+ # from .utils.scheduler_manager import SchedulerManager
- scheduler_manager = SchedulerManager()
- scheduler_manager.init_scheduler(app)
+ # scheduler_manager = SchedulerManager()
+ # scheduler_manager.init_scheduler(app)
- # 检查是否启用定时任务
- scheduler_enabled = getattr(app.config, 'SCHEDULER_ENABLED', True)
- if scheduler_enabled:
- # 从配置获取重建间隔
- rebuild_interval = getattr(app.config, 'GRAPH_REBUILD_INTERVAL', 1)
- scheduler_manager.start_graph_rebuild_task(interval_minutes=rebuild_interval)
+ # # 检查是否启用定时任务
+ # scheduler_enabled = getattr(app.config, 'SCHEDULER_ENABLED', True)
+ # if scheduler_enabled:
+ # # 从配置获取重建间隔
+ # rebuild_interval = getattr(app.config, 'GRAPH_REBUILD_INTERVAL', 1)
+ # scheduler_manager.start_graph_rebuild_task(interval_minutes=rebuild_interval)
- # 注册关闭时的清理函数
- atexit.register(lambda: scheduler_manager.shutdown())
+ # # 注册关闭时的清理函数
+ # atexit.register(lambda: scheduler_manager.shutdown())
return app
diff --git a/Merge/back_rhj/app/__pycache__/__init__.cpython-312.pyc b/Merge/back_rhj/app/__pycache__/__init__.cpython-312.pyc
index 59d6618..6098e13 100644
--- a/Merge/back_rhj/app/__pycache__/__init__.cpython-312.pyc
+++ b/Merge/back_rhj/app/__pycache__/__init__.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_rhj/app/__pycache__/routes.cpython-312.pyc b/Merge/back_rhj/app/__pycache__/routes.cpython-312.pyc
index 696eaf4..f1d3c73 100644
--- a/Merge/back_rhj/app/__pycache__/routes.cpython-312.pyc
+++ b/Merge/back_rhj/app/__pycache__/routes.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_rhj/app/blueprints/__pycache__/recommend.cpython-312.pyc b/Merge/back_rhj/app/blueprints/__pycache__/recommend.cpython-312.pyc
index fc734ad..75ccdab 100644
--- a/Merge/back_rhj/app/blueprints/__pycache__/recommend.cpython-312.pyc
+++ b/Merge/back_rhj/app/blueprints/__pycache__/recommend.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_rhj/app/blueprints/__pycache__/scheduler.cpython-312.pyc b/Merge/back_rhj/app/blueprints/__pycache__/scheduler.cpython-312.pyc
index 57040f1..d574676 100644
--- a/Merge/back_rhj/app/blueprints/__pycache__/scheduler.cpython-312.pyc
+++ b/Merge/back_rhj/app/blueprints/__pycache__/scheduler.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_rhj/app/functions/__pycache__/FAuth.cpython-312.pyc b/Merge/back_rhj/app/functions/__pycache__/FAuth.cpython-312.pyc
index a806a51..6c0297b 100644
--- a/Merge/back_rhj/app/functions/__pycache__/FAuth.cpython-312.pyc
+++ b/Merge/back_rhj/app/functions/__pycache__/FAuth.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_rhj/app/models/__pycache__/__init__.cpython-312.pyc b/Merge/back_rhj/app/models/__pycache__/__init__.cpython-312.pyc
index 13b00b1..8eec580 100644
--- a/Merge/back_rhj/app/models/__pycache__/__init__.cpython-312.pyc
+++ b/Merge/back_rhj/app/models/__pycache__/__init__.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_rhj/app/models/__pycache__/email_verification.cpython-312.pyc b/Merge/back_rhj/app/models/__pycache__/email_verification.cpython-312.pyc
index 7a02a9f..c9ad75d 100644
--- a/Merge/back_rhj/app/models/__pycache__/email_verification.cpython-312.pyc
+++ b/Merge/back_rhj/app/models/__pycache__/email_verification.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_rhj/app/models/__pycache__/users.cpython-312.pyc b/Merge/back_rhj/app/models/__pycache__/users.cpython-312.pyc
index 1cd3627..1af05fe 100644
--- a/Merge/back_rhj/app/models/__pycache__/users.cpython-312.pyc
+++ b/Merge/back_rhj/app/models/__pycache__/users.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_rhj/app/models/recall/__pycache__/__init__.cpython-312.pyc b/Merge/back_rhj/app/models/recall/__pycache__/__init__.cpython-312.pyc
index ec1bb4b..88c8123 100644
--- a/Merge/back_rhj/app/models/recall/__pycache__/__init__.cpython-312.pyc
+++ b/Merge/back_rhj/app/models/recall/__pycache__/__init__.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_rhj/app/models/recall/__pycache__/ad_recall.cpython-312.pyc b/Merge/back_rhj/app/models/recall/__pycache__/ad_recall.cpython-312.pyc
index 372104d..ed8dbc9 100644
--- a/Merge/back_rhj/app/models/recall/__pycache__/ad_recall.cpython-312.pyc
+++ b/Merge/back_rhj/app/models/recall/__pycache__/ad_recall.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_rhj/app/models/recall/__pycache__/hot_recall.cpython-312.pyc b/Merge/back_rhj/app/models/recall/__pycache__/hot_recall.cpython-312.pyc
index de7e3f9..3cfdd43 100644
--- a/Merge/back_rhj/app/models/recall/__pycache__/hot_recall.cpython-312.pyc
+++ b/Merge/back_rhj/app/models/recall/__pycache__/hot_recall.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_rhj/app/models/recall/__pycache__/multi_recall_manager.cpython-312.pyc b/Merge/back_rhj/app/models/recall/__pycache__/multi_recall_manager.cpython-312.pyc
index 0b05f7e..9e1d7c8 100644
--- a/Merge/back_rhj/app/models/recall/__pycache__/multi_recall_manager.cpython-312.pyc
+++ b/Merge/back_rhj/app/models/recall/__pycache__/multi_recall_manager.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_rhj/app/models/recall/__pycache__/swing_recall.cpython-312.pyc b/Merge/back_rhj/app/models/recall/__pycache__/swing_recall.cpython-312.pyc
index 87bc373..91fa864 100644
--- a/Merge/back_rhj/app/models/recall/__pycache__/swing_recall.cpython-312.pyc
+++ b/Merge/back_rhj/app/models/recall/__pycache__/swing_recall.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_rhj/app/models/recall/__pycache__/usercf_recall.cpython-312.pyc b/Merge/back_rhj/app/models/recall/__pycache__/usercf_recall.cpython-312.pyc
index e5dc324..e212bf5 100644
--- a/Merge/back_rhj/app/models/recall/__pycache__/usercf_recall.cpython-312.pyc
+++ b/Merge/back_rhj/app/models/recall/__pycache__/usercf_recall.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_rhj/app/models/recall/swing_recall.py b/Merge/back_rhj/app/models/recall/swing_recall.py
index bf7fdd6..5bab5b7 100644
--- a/Merge/back_rhj/app/models/recall/swing_recall.py
+++ b/Merge/back_rhj/app/models/recall/swing_recall.py
@@ -36,7 +36,7 @@
WHERE type IN ('like', 'favorite', 'comment')
""")
interactions = cursor.fetchall()
-
+ print(f"获取到{len(interactions)}条用户-物品交互数据")
for user_id, post_id in interactions:
self.user_items[user_id].add(post_id)
self.item_users[post_id].add(user_id)
diff --git a/Merge/back_rhj/app/models/recommend/__pycache__/LightGCN.cpython-312.pyc b/Merge/back_rhj/app/models/recommend/__pycache__/LightGCN.cpython-312.pyc
index 48bb03f..f7079b8 100644
--- a/Merge/back_rhj/app/models/recommend/__pycache__/LightGCN.cpython-312.pyc
+++ b/Merge/back_rhj/app/models/recommend/__pycache__/LightGCN.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_rhj/app/models/recommend/__pycache__/base_model.cpython-312.pyc b/Merge/back_rhj/app/models/recommend/__pycache__/base_model.cpython-312.pyc
index 204d2a7..19bf281 100644
--- a/Merge/back_rhj/app/models/recommend/__pycache__/base_model.cpython-312.pyc
+++ b/Merge/back_rhj/app/models/recommend/__pycache__/base_model.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_rhj/app/models/recommend/__pycache__/operators.cpython-312.pyc b/Merge/back_rhj/app/models/recommend/__pycache__/operators.cpython-312.pyc
index 4e24e5b..28de5cd 100644
--- a/Merge/back_rhj/app/models/recommend/__pycache__/operators.cpython-312.pyc
+++ b/Merge/back_rhj/app/models/recommend/__pycache__/operators.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_rhj/app/routes.py b/Merge/back_rhj/app/routes.py
index f123a84..6f159ca 100644
--- a/Merge/back_rhj/app/routes.py
+++ b/Merge/back_rhj/app/routes.py
@@ -1,6 +1,7 @@
from flask import Blueprint, request, jsonify
from .functions.FAuth import FAuth
-from .services.recommendation_service import RecommendationService
+from app.services.recommendation_service import RecommendationService
+from app.utils.graph_build import build_user_post_graph
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from config import Config
@@ -17,7 +18,10 @@
@wraps(f)
def decorated(*args, **kwargs):
token = request.headers.get('Authorization')
+ print(f"收到的Authorization头: {token}")
+
if not token:
+ print("缺少Authorization头")
return jsonify({'success': False, 'message': '缺少访问令牌'}), 401
session = None
@@ -25,22 +29,35 @@
# 移除Bearer前缀
if token.startswith('Bearer '):
token = token[7:]
+ print(f"提取的token: {token[:20]}...")
engine = create_engine(Config.SQLURL)
SessionLocal = sessionmaker(bind=engine)
session = SessionLocal()
f_auth = FAuth(session)
+ # 验证token
+ token_data = f_auth.verify_token(token)
+ print(f"Token验证结果: {token_data}")
+
+ if not token_data:
+ print("Token验证失败 - token无效")
+ return jsonify({'success': False, 'message': '无效的访问令牌'}), 401
+
user = f_auth.get_user_by_token(token)
if not user:
+ print("根据token获取用户失败")
return jsonify({'success': False, 'message': '无效的访问令牌'}), 401
+ print(f"Token验证成功,用户: {user.username}, ID: {user.id}")
+
# 将用户信息传递给路由函数
return f(user, *args, **kwargs)
except Exception as e:
+ print(f"Token验证异常: {str(e)}")
if session:
session.rollback()
- return jsonify({'success': False, 'message': '令牌验证失败'}), 401
+ return jsonify({'success': False, 'message': f'令牌验证失败: {str(e)}'}), 401
finally:
if session:
session.close()
@@ -368,12 +385,12 @@
try:
data = request.get_json() or {}
user_id = data.get('user_id') or current_user.id
- topk = data.get('topk', 10) # 默认推荐10个
- print(f"为用户 {user_id} 获取推荐,数量: {topk}")
+ print(f"为用户 {user_id} 获取个性化推荐")
# 调用推荐系统
- recommendations = recommendation_service.get_recommendations(user_id, topk)
+ user2idx, post2idx = build_user_post_graph(return_mapping=True)
+ recommendations = recommendation_service.get_recommendations(float(user_id), topk=10)
return jsonify({
'success': True,
diff --git a/Merge/back_rhj/app/services/__pycache__/lightgcn_scorer.cpython-312.pyc b/Merge/back_rhj/app/services/__pycache__/lightgcn_scorer.cpython-312.pyc
index bd899a9..5e2f64b 100644
--- a/Merge/back_rhj/app/services/__pycache__/lightgcn_scorer.cpython-312.pyc
+++ b/Merge/back_rhj/app/services/__pycache__/lightgcn_scorer.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_rhj/app/services/__pycache__/recommendation_service.cpython-312.pyc b/Merge/back_rhj/app/services/__pycache__/recommendation_service.cpython-312.pyc
index 0446ed2..8eac212 100644
--- a/Merge/back_rhj/app/services/__pycache__/recommendation_service.cpython-312.pyc
+++ b/Merge/back_rhj/app/services/__pycache__/recommendation_service.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_rhj/app/services/lightgcn_scorer.py b/Merge/back_rhj/app/services/lightgcn_scorer.py
index f6aeb19..30cddd4 100644
--- a/Merge/back_rhj/app/services/lightgcn_scorer.py
+++ b/Merge/back_rhj/app/services/lightgcn_scorer.py
@@ -121,6 +121,8 @@
List[float]: 每个候选物品的LightGCN分数
"""
self._initialize_model()
+ print(self.user2idx, "用户映射")
+ print(self.post2idx, "物品映射")
# 检查用户是否存在
if user_id not in self.user2idx:
diff --git a/Merge/back_rhj/app/services/recommendation_service.py b/Merge/back_rhj/app/services/recommendation_service.py
index 0547f7b..8982bd3 100644
--- a/Merge/back_rhj/app/services/recommendation_service.py
+++ b/Merge/back_rhj/app/services/recommendation_service.py
@@ -27,7 +27,7 @@
args.data_path = './app/user_post_graph.txt' # 修改为帖子图文件
args.pre_model_path = './app/models/recommend/LightGCN_pretrained.pt'
- self.topk = 2 # 默认推荐数量
+ self.topk = 10 # 默认推荐数量
# 初始化多路召回管理器
self.multi_recall = None
@@ -82,7 +82,7 @@
return intersection / union if union > 0 else 0.0
- def mmr_rerank_with_ads(self, post_ids, scores, theta=0.5, target_size=None):
+ def mmr_rerank_with_ads(self, post_ids, scores, theta=0.7, target_size=None):
"""
使用MMR算法重新排序推荐结果,并在过程中加入广告约束
输入:
diff --git a/Merge/back_rhj/app/user_post_graph.txt b/Merge/back_rhj/app/user_post_graph.txt
index f2f2e58..43edcc7 100644
--- a/Merge/back_rhj/app/user_post_graph.txt
+++ b/Merge/back_rhj/app/user_post_graph.txt
@@ -1,7 +1,13 @@
-0 0 0 1 0 1 0 1 1749827292 1749953091 1749953091 1749953480 1749953480 1749954059 1749954059 1 1 2 1 2 1 2
-1 1 0 3 1749827292 1749955282 1749955282 5 2 5
-2 1 0 0 1 1 1749955282 1750372189 1750372215 1750372231 1750372241 5 3 2 3 2
-3 0 1749954059 2
-4 1 1749954059 5
-5 2 1749955282 2
-6 1 3 0 3 0 1750372862 1750372873 1750373592 1750374867 1750392753 3 3 2 2 3
+0 0 0 1 2 2 1 0 0 1 1749827292 1749953091 1749953091 1749953091 1749953480 1749953480 1749953480 1749954059 1749954059 1 1 2 1 1 2 1 1 2
+1 1 4 0 1749827292 1749955282 1749955282 5 5 2
+2 2 2 1 0 0 1 1 1749953091 1749953480 1749955282 1750372189 1750372215 1750372231 1750372241 5 5 5 3 2 3 2
+3 2 2 0 2 1749953091 1749953480 1749954059 1749955282 5 5 2 1
+4 2 2 1 1749953091 1749953480 1749954059 1 1 5
+5 3 1749955282 2
+6 8 1 6 5 5 1750406052 1750410775 1750410789 1750814082 1750814094 2 2 2 2 3
+7 9 1750751914 2
+8 0 1750459840 2
+9 1 4 0 4 0 5 6 6 7 7 1750372862 1750372873 1750373592 1750374867 1750392753 1750400557 1750401552 1750401563 1750401600 1750401789 3 3 2 2 3 3 3 3 3 3
+10 6 6 8 1750405296 1750405430 1750459720 2 3 2
+11 6 1750406518 3
+12 0 0 1750438409 1750481198 2 5
diff --git a/Merge/back_rhj/app/utils/__pycache__/data_loader.cpython-312.pyc b/Merge/back_rhj/app/utils/__pycache__/data_loader.cpython-312.pyc
index 70405e3..8157bf8 100644
--- a/Merge/back_rhj/app/utils/__pycache__/data_loader.cpython-312.pyc
+++ b/Merge/back_rhj/app/utils/__pycache__/data_loader.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_rhj/app/utils/__pycache__/graph_build.cpython-312.pyc b/Merge/back_rhj/app/utils/__pycache__/graph_build.cpython-312.pyc
index 6fa5bc6..e1676da 100644
--- a/Merge/back_rhj/app/utils/__pycache__/graph_build.cpython-312.pyc
+++ b/Merge/back_rhj/app/utils/__pycache__/graph_build.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_rhj/app/utils/__pycache__/parse_args.cpython-312.pyc b/Merge/back_rhj/app/utils/__pycache__/parse_args.cpython-312.pyc
index 9295682..ba17fcf 100644
--- a/Merge/back_rhj/app/utils/__pycache__/parse_args.cpython-312.pyc
+++ b/Merge/back_rhj/app/utils/__pycache__/parse_args.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_rhj/app/utils/__pycache__/scheduler_manager.cpython-312.pyc b/Merge/back_rhj/app/utils/__pycache__/scheduler_manager.cpython-312.pyc
index 89f68ad..0f67d6a 100644
--- a/Merge/back_rhj/app/utils/__pycache__/scheduler_manager.cpython-312.pyc
+++ b/Merge/back_rhj/app/utils/__pycache__/scheduler_manager.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_rhj/test_redbook_recommendation.py b/Merge/back_rhj/test_redbook_recommendation.py
index 325def5..d5dfcd3 100644
--- a/Merge/back_rhj/test_redbook_recommendation.py
+++ b/Merge/back_rhj/test_redbook_recommendation.py
@@ -120,8 +120,11 @@
result = cursor.fetchone()
if result:
- user_id = result[0]
+ user_id = 33
+ cursor.execute("select username from users where id = %s", (user_id,))
+ username = cursor.fetchone()[0]
print(f"测试用户ID: {user_id}")
+ print(f"测试用户名: {username}")
# 查看用户的历史行为
cursor.execute("""
@@ -250,11 +253,11 @@
print("=" * 50)
tests = [
- test_database_connection,
+ # test_database_connection,
test_graph_building,
- test_cold_start_recommendation,
+ # test_cold_start_recommendation,
test_user_recommendation,
- test_recommendation_performance
+ # test_recommendation_performance
]
passed = 0
diff --git a/Merge/front/src/components/PostDetailJWLLL.jsx b/Merge/front/src/components/PostDetailJWLLL.jsx
index 417105a..9304b39 100644
--- a/Merge/front/src/components/PostDetailJWLLL.jsx
+++ b/Merge/front/src/components/PostDetailJWLLL.jsx
@@ -8,7 +8,7 @@
import MediaPreview from './MediaPreview'
import '../style/PostDetail.css'
import dayjs from 'dayjs'
-import { followUser, unfollowUser } from '../api/api_ljc'
+import { followUser, unfollowUser ,getUserFollowing} from '../api/api_ljc'
export default function PostDetail() {
const { id } = useParams()
@@ -67,24 +67,33 @@
}, [id])
// 检查当前用户是否已关注发帖人
- useEffect(() => {
- if (post && post.user_id) {
- // 这里假设有API postsAPI.getUserFollowing
- const checkFollow = async () => {
- try {
- const userInfo = getUserInfo()
- if (!userInfo?.id) return
- const res = await postsAPI.getUserFollowing(userInfo.id)
- if (Array.isArray(res)) {
- setIsFollowing(res.some(u => u.id === post.user_id))
- } else if (Array.isArray(res.following)) {
- setIsFollowing(res.following.some(u => u.id === post.user_id))
- }
- } catch {}
- }
- checkFollow()
- }
- }, [post])
+ const checkFollowStatus = useCallback(async (postUserId) => {
+ if (!postUserId) return;
+
+ const currentUserId = getCurrentUserId();
+ if (!currentUserId) return;
+
+ try {
+ const response = await getUserFollowing(currentUserId);
+ // 处理不同的响应结构
+ const followingList = Array.isArray(response) ? response : (response.data || []);
+
+ console.log(response)
+ // 检查目标用户是否在关注列表中
+ setIsFollowing(
+ followingList.some(user => user.id === postUserId)
+ );
+ } catch (error) {
+ console.error('获取关注状态失败:', error);
+ }
+}, []);
+
+// 当帖子数据加载后,检查关注状态
+useEffect(() => {
+ if (post && post.user_id) {
+ checkFollowStatus(post.user_id);
+ }
+}, [post, checkFollowStatus])
// 拉取发帖人信息
useEffect(() => {
@@ -319,24 +328,24 @@
</span>
{/* 关注按钮 */}
{post.user_id && (
- <button
- className={`follow-btn ${isFollowing ? 'following' : ''}`}
- onClick={handleFollowAction}
- disabled={followLoading}
- style={{
- marginLeft: '12px',
- padding: '4px 12px',
- borderRadius: '20px',
- border: '1px solid #ccc',
- background: isFollowing ? '#f0f0f0' : '#007bff',
- color: isFollowing ? '#333' : 'white',
- cursor: 'pointer',
- fontSize: '14px'
- }}
- >
- {followLoading ? '处理中...' : (isFollowing ? '已关注' : '关注')}
- </button>
- )}
+ <button
+ className={`follow-btn ${isFollowing ? 'following' : ''}`}
+ onClick={handleFollowAction}
+ disabled={followLoading}
+ style={{
+ marginLeft: '12px',
+ padding: '4px 12px',
+ borderRadius: '20px',
+ border: '1px solid #ccc',
+ background: isFollowing ? '#f0f0f0' : '#007bff',
+ color: isFollowing ? '#333' : 'white',
+ cursor: 'pointer',
+ fontSize: '14px'
+ }}
+ >
+ {followLoading ? '处理中...' : (isFollowing ? '已关注' : '关注')}
+ </button>
+ )}
</div>
</div>
<div className="post-stats">