mickeywu520 commited on
Commit
3887148
·
1 Parent(s): 751a827

新增debug訊息

Browse files
backend/services/enhanced_product_service.py CHANGED
@@ -43,16 +43,20 @@ class EnhancedProductService:
43
  """
44
  db = None
45
  try:
 
46
  db = get_database_session()
47
-
48
  # 建立基本查詢,預載入分類資訊
49
  query = db.query(Product).options(
50
  joinedload(Product.category)
51
  ).filter(Product.is_deleted == False)
52
-
53
  # 關鍵字搜尋 - 支援商品名稱、編號、條碼
54
  if query_text:
 
55
  search_terms = query_text.strip().split()
 
 
56
  for term in search_terms:
57
  search_filter = or_(
58
  Product.productName.ilike(f"%{term}%"),
@@ -214,13 +218,22 @@ class EnhancedProductService:
214
  """
215
  db = None
216
  try:
 
217
  db = get_database_session()
218
-
 
 
 
 
 
 
219
  # 分析查詢關鍵字
220
  keywords = self._extract_keywords(query_text)
 
221
 
222
  # 建立推薦查詢
223
  query = db.query(Product).filter(Product.is_deleted == False)
 
224
 
225
  # 多關鍵字匹配 - 使用 OR 邏輯,任一關鍵字匹配即可
226
  if keywords:
@@ -232,17 +245,34 @@ class EnhancedProductService:
232
  Product.barcode.ilike(f"%{keyword}%")
233
  ])
234
 
 
 
235
  # 使用 OR 連接所有搜尋條件
236
  if search_filters:
237
  query = query.filter(or_(*search_filters))
238
-
 
 
 
 
 
239
  # 優先顯示有庫存的商品
240
  query = query.order_by(Product.stock.desc())
241
-
242
  products = query.options(joinedload(Product.category)).limit(limit).all()
 
243
 
244
  data = []
245
  for product in products:
 
 
 
 
 
 
 
 
 
246
  data.append({
247
  "id": product.id,
248
  "product_code": product.productCode,
@@ -251,10 +281,12 @@ class EnhancedProductService:
251
  "unit": product.unit,
252
  "category_name": product.category.name if product.category else None,
253
  "warehouse": product.warehouse,
254
- "recommendation_reason": f"符合關鍵字: {', '.join(keywords)}",
255
  "availability": "有庫存" if product.stock > 0 else "缺貨"
256
  })
257
-
 
 
258
  return DatabaseResult(
259
  success=True,
260
  data=data,
@@ -262,7 +294,9 @@ class EnhancedProductService:
262
  )
263
 
264
  except Exception as e:
265
- logger.error(f"商品推薦錯誤: {str(e)}")
 
 
266
  return DatabaseResult(
267
  success=False,
268
  error=f"商品推薦失敗: {str(e)}"
 
43
  """
44
  db = None
45
  try:
46
+ logger.info(f"🔍 開始進階商品搜尋: '{query_text}'")
47
  db = get_database_session()
48
+
49
  # 建立基本查詢,預載入分類資訊
50
  query = db.query(Product).options(
51
  joinedload(Product.category)
52
  ).filter(Product.is_deleted == False)
53
+
54
  # 關鍵字搜尋 - 支援商品名稱、編號、條碼
55
  if query_text:
56
+ logger.info(f"🔑 使用關鍵字搜尋: '{query_text}'")
57
  search_terms = query_text.strip().split()
58
+ logger.info(f"📝 分割的搜尋詞: {search_terms}")
59
+
60
  for term in search_terms:
61
  search_filter = or_(
62
  Product.productName.ilike(f"%{term}%"),
 
218
  """
219
  db = None
220
  try:
221
+ logger.info(f"🛍️ 開始商品推薦查詢: '{query_text}'")
222
  db = get_database_session()
223
+
224
+ if not db:
225
+ logger.error(f"❌ 無法獲取資料庫連接")
226
+ return DatabaseResult(success=False, error="資料庫連接失敗")
227
+
228
+ logger.info(f"✅ 資料庫連接成功")
229
+
230
  # 分析查詢關鍵字
231
  keywords = self._extract_keywords(query_text)
232
+ logger.info(f"🔑 推薦查詢關鍵字: {keywords}")
233
 
234
  # 建立推薦查詢
235
  query = db.query(Product).filter(Product.is_deleted == False)
236
+ logger.info(f"📊 基礎查詢建立完成")
237
 
238
  # 多關鍵字匹配 - 使用 OR 邏輯,任一關鍵字匹配即可
239
  if keywords:
 
245
  Product.barcode.ilike(f"%{keyword}%")
246
  ])
247
 
248
+ logger.info(f"🔍 建立了 {len(search_filters)} 個搜尋條件")
249
+
250
  # 使用 OR 連接所有搜尋條件
251
  if search_filters:
252
  query = query.filter(or_(*search_filters))
253
+ logger.info(f"✅ 搜尋條件已應用")
254
+ else:
255
+ logger.warning(f"⚠️ 沒有搜尋條件")
256
+ else:
257
+ logger.warning(f"⚠️ 沒有關鍵字,將返回所有商品")
258
+
259
  # 優先顯示有庫存的商品
260
  query = query.order_by(Product.stock.desc())
261
+
262
  products = query.options(joinedload(Product.category)).limit(limit).all()
263
+ logger.info(f"📦 查詢到 {len(products)} 個商品")
264
 
265
  data = []
266
  for product in products:
267
+ # 檢查哪個關鍵字匹配了這個商品
268
+ matched_keywords = []
269
+ for keyword in keywords:
270
+ if (keyword.lower() in product.productName.lower() or
271
+ keyword.lower() in product.productCode.lower()):
272
+ matched_keywords.append(keyword)
273
+
274
+ logger.info(f"📦 商品: {product.productName} - 匹配關鍵字: {matched_keywords}")
275
+
276
  data.append({
277
  "id": product.id,
278
  "product_code": product.productCode,
 
281
  "unit": product.unit,
282
  "category_name": product.category.name if product.category else None,
283
  "warehouse": product.warehouse,
284
+ "recommendation_reason": f"符合關鍵字: {', '.join(matched_keywords[:3]) if matched_keywords else '一般推薦'}",
285
  "availability": "有庫存" if product.stock > 0 else "缺貨"
286
  })
287
+
288
+ logger.info(f"✅ 推薦查詢完成,返回 {len(data)} 個商品")
289
+
290
  return DatabaseResult(
291
  success=True,
292
  data=data,
 
294
  )
295
 
296
  except Exception as e:
297
+ logger.error(f"商品推薦錯誤: {str(e)}")
298
+ import traceback
299
+ logger.error(f"📋 錯誤詳情: {traceback.format_exc()}")
300
  return DatabaseResult(
301
  success=False,
302
  error=f"商品推薦失敗: {str(e)}"
backend/services/pydantic_ai_service.py CHANGED
@@ -193,10 +193,14 @@ class ProductQueryService:
193
  查詢結果字典
194
  """
195
  try:
 
 
196
  # 分析查詢意圖
197
  intent_analysis = self.analyze_query_intent(user_message)
 
198
 
199
  if not intent_analysis["is_product_query"]:
 
200
  return {
201
  "success": False,
202
  "text": "這似乎不是商品查詢,請嘗試其他功能。",
@@ -206,12 +210,14 @@ class ProductQueryService:
206
 
207
  # 根據意圖類型選擇查詢方法
208
  if intent_analysis["is_recommendation"]:
 
209
  # 推薦查詢
210
  result = self.enhanced_product_service.get_product_recommendations(
211
  query_text=user_message,
212
  limit=5
213
  )
214
  else:
 
215
  # 一般搜尋
216
  result = self.enhanced_product_service.search_products_advanced(
217
  query_text=user_message,
@@ -219,6 +225,8 @@ class ProductQueryService:
219
  limit=10
220
  )
221
 
 
 
222
  # 格式化回應
223
  if result.success and result.data:
224
  response_text = self._format_product_response(result.data, intent_analysis)
@@ -244,7 +252,9 @@ class ProductQueryService:
244
  }
245
 
246
  except Exception as e:
247
- logger.error(f"同步商品查詢錯誤: {str(e)}")
 
 
248
  return {
249
  "success": False,
250
  "text": f"抱歉,商品查詢時發生錯誤:{str(e)}",
 
193
  查詢結果字典
194
  """
195
  try:
196
+ logger.info(f"🔍 Pydantic AI 開始處理商品查詢: '{user_message}'")
197
+
198
  # 分析查詢意圖
199
  intent_analysis = self.analyze_query_intent(user_message)
200
+ logger.info(f"📊 意圖分析結果: {intent_analysis}")
201
 
202
  if not intent_analysis["is_product_query"]:
203
+ logger.warning(f"❌ 非商品查詢意圖,拒絕處理")
204
  return {
205
  "success": False,
206
  "text": "這似乎不是商品查詢,請嘗試其他功能。",
 
210
 
211
  # 根據意圖類型選擇查詢方法
212
  if intent_analysis["is_recommendation"]:
213
+ logger.info(f"🛍️ 執行推薦查詢")
214
  # 推薦查詢
215
  result = self.enhanced_product_service.get_product_recommendations(
216
  query_text=user_message,
217
  limit=5
218
  )
219
  else:
220
+ logger.info(f"🔍 執行一般搜尋")
221
  # 一般搜尋
222
  result = self.enhanced_product_service.search_products_advanced(
223
  query_text=user_message,
 
225
  limit=10
226
  )
227
 
228
+ logger.info(f"📋 查詢結果: 成功={result.success}, 數量={result.count}, 錯誤={result.error}")
229
+
230
  # 格式化回應
231
  if result.success and result.data:
232
  response_text = self._format_product_response(result.data, intent_analysis)
 
252
  }
253
 
254
  except Exception as e:
255
+ logger.error(f"同步商品查詢錯誤: {str(e)}")
256
+ import traceback
257
+ logger.error(f"📋 錯誤詳情: {traceback.format_exc()}")
258
  return {
259
  "success": False,
260
  "text": f"抱歉,商品查詢時發生錯誤:{str(e)}",
test_debug_logs.py ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ 測試調試日誌是否正常工作
3
+ """
4
+
5
+ import logging
6
+
7
+ # 設置日誌格式
8
+ logging.basicConfig(
9
+ level=logging.INFO,
10
+ format='%(levelname)s:%(name)s:%(message)s'
11
+ )
12
+
13
+ def test_keyword_extraction_with_logs():
14
+ """測試關鍵字提取並顯示日誌"""
15
+
16
+ def extract_keywords_with_logs(query_text: str):
17
+ """帶日誌的關鍵字提取"""
18
+ logger = logging.getLogger("test_keyword_extraction")
19
+
20
+ # 移除常見的查詢詞彙
21
+ stop_words = ['推薦', '有沒有', '是否有', '請問', '想要', '需要', '找', '查詢', '搜尋', '還有嗎', '還有', '嗎', '可以']
22
+
23
+ # 清理查詢文字
24
+ cleaned_text = query_text.replace('?', '').replace('?', '').strip()
25
+ logger.info(f"清理後的文字: '{cleaned_text}'")
26
+
27
+ # 先嘗試提取核心商品詞彙
28
+ core_product_words = ['貓砂', '狗糧', '寵物', '商品', '產品', '貓', '狗', '犬', '礦砂']
29
+ extracted_core_words = []
30
+
31
+ for core_word in core_product_words:
32
+ if core_word in cleaned_text:
33
+ extracted_core_words.append(core_word)
34
+
35
+ logger.info(f"提取的核心詞彙: {extracted_core_words}")
36
+
37
+ # 分割並清理關鍵字
38
+ words = cleaned_text.split()
39
+ keywords = []
40
+
41
+ for word in words:
42
+ if word not in stop_words and len(word) > 1:
43
+ keywords.append(word)
44
+
45
+ logger.info(f"分割後的關鍵字: {keywords}")
46
+
47
+ # 合併核心詞彙和分割的關鍵字
48
+ all_keywords = list(set(extracted_core_words + keywords))
49
+ logger.info(f"合併後的關鍵字: {all_keywords}")
50
+
51
+ # 如果沒有有效關鍵字,使用清理後的文字
52
+ if not all_keywords:
53
+ all_keywords = [cleaned_text]
54
+ logger.warning(f"沒有有效關鍵字,使用原始文字: {all_keywords}")
55
+
56
+ # 擴展相關關鍵字
57
+ expanded_keywords = []
58
+ for keyword in all_keywords:
59
+ expanded_keywords.append(keyword)
60
+
61
+ # 貓砂相關擴展
62
+ if '貓砂' in keyword or '貓' in keyword:
63
+ expanded_keywords.extend(['礦砂', '豆腐砂', '水晶砂', '木屑砂', 'litter', '貓砂'])
64
+ logger.info(f"貓砂相關擴展: {keyword} → 添加貓砂相關詞彙")
65
+
66
+ # 狗糧相關擴展
67
+ if '狗糧' in keyword or '狗' in keyword:
68
+ expanded_keywords.extend(['犬糧', '犬種', '狗食', 'dog'])
69
+ logger.info(f"狗糧相關擴展: {keyword} → 添加狗糧相關詞彙")
70
+
71
+ # 寵物相關擴展
72
+ if '寵物' in keyword:
73
+ expanded_keywords.extend(['貓', '狗', '犬', 'pet', 'cat'])
74
+ logger.info(f"寵物相關擴展: {keyword} → 添加寵物相關詞彙")
75
+
76
+ # 商品相關擴展
77
+ if '商品' in keyword or '產品' in keyword:
78
+ expanded_keywords.extend(['貓砂', '狗糧', '寵物', '食品', '用品'])
79
+ logger.info(f"商品相關擴展: {keyword} → 添加商品相關詞彙")
80
+
81
+ # 去除重複並返回
82
+ unique_keywords = list(set(expanded_keywords))
83
+
84
+ # 記錄關鍵字提取結果用於調試
85
+ logger.info(f"關鍵字提取: '{query_text}' → 核心詞: {extracted_core_words} → 最終: {unique_keywords}")
86
+
87
+ return unique_keywords, extracted_core_words
88
+
89
+ print("🔍 測試關鍵字提取日誌")
90
+ print("=" * 50)
91
+
92
+ test_queries = [
93
+ "請問貓砂還有嗎?",
94
+ "貓砂還有嗎?",
95
+ "請問有商品可以推薦嗎?"
96
+ ]
97
+
98
+ for query in test_queries:
99
+ print(f"\n測試查詢: '{query}'")
100
+ print("-" * 30)
101
+ keywords, core_words = extract_keywords_with_logs(query)
102
+ print(f"最終結果: {keywords}")
103
+
104
+ def test_product_matching_simulation():
105
+ """模擬商品匹配過程"""
106
+
107
+ logger = logging.getLogger("test_product_matching")
108
+
109
+ # 實際商品資料
110
+ products = [
111
+ {
112
+ "id": 2,
113
+ "productCode": "SW-06-01",
114
+ "productName": "Shovel well豪好鏟 破碎型礦砂",
115
+ "stock": 50,
116
+ "is_deleted": False
117
+ },
118
+ {
119
+ "id": 3,
120
+ "productCode": "TL-03",
121
+ "productName": "美國極冠貓砂 薰衣草12kg",
122
+ "stock": 48,
123
+ "is_deleted": False
124
+ }
125
+ ]
126
+
127
+ print(f"\n🛍️ 測試商品匹配模擬")
128
+ print("=" * 50)
129
+
130
+ test_query = "貓砂還有嗎?"
131
+ logger.info(f"開始商品匹配測試: '{test_query}'")
132
+
133
+ # 模擬關鍵字提取
134
+ keywords = ['貓', '水晶砂', '貓砂', '豆腐砂', 'litter', '木屑砂', '礦砂', '貓砂還有嗎']
135
+ logger.info(f"使用關鍵字: {keywords}")
136
+
137
+ # ��擬商品匹配
138
+ matched_products = []
139
+
140
+ for product in products:
141
+ if product["is_deleted"]:
142
+ continue
143
+
144
+ # 檢查哪個關鍵字匹配了這個商品
145
+ matched_keywords = []
146
+ for keyword in keywords:
147
+ if (keyword.lower() in product["productName"].lower() or
148
+ keyword.lower() in product["productCode"].lower()):
149
+ matched_keywords.append(keyword)
150
+
151
+ if matched_keywords:
152
+ matched_products.append(product)
153
+ logger.info(f"📦 商品: {product['productName']} - 匹配關鍵字: {matched_keywords}")
154
+
155
+ logger.info(f"✅ 匹配完成,找到 {len(matched_products)} 個商品")
156
+
157
+ print(f"匹配結果: 找到 {len(matched_products)} 個商品")
158
+ for product in matched_products:
159
+ print(f" - {product['productName']}")
160
+
161
+ def main():
162
+ """主函數"""
163
+ print("🚀 測試調試日誌功能")
164
+ print("=" * 60)
165
+
166
+ test_keyword_extraction_with_logs()
167
+ test_product_matching_simulation()
168
+
169
+ print("\n" + "=" * 60)
170
+ print("✅ 日誌測試完成!")
171
+ print("\n💡 現在重啟服務,應該能看到詳細的調試日誌")
172
+
173
+ if __name__ == "__main__":
174
+ main()