fix: backend improvements (customer health, tests, middleware, corpus)

This commit is contained in:
wlt
2026-06-24 10:38:26 +08:00
parent eb39cc1baa
commit ad329815fa
11 changed files with 122 additions and 77 deletions
+40 -5
View File
@@ -233,6 +233,12 @@ class CustomerHealthService:
score = max(0, min(100, 80 - recent_hours * 3))
return {"score": round(score), "recent_avg_hours": round(recent_hours, 1), "trend": "declining"}
@staticmethod
def _words_in_text(words, text_words):
"""Check if all words in the phrase appear in the text word set.
Handles multi-word phrases where word order differs."""
return all(w in text_words for w in words)
@staticmethod
def calc_sentiment_score(messages: List[str]) -> Dict[str, Any]:
if not messages:
@@ -240,11 +246,22 @@ class CustomerHealthService:
positive = 0
negative = 0
for msg in messages:
lower = msg.lower()
if any(w in lower for w in POSITIVE_WORDS):
positive += 1
if any(w in lower for w in NEGATIVE_WORDS):
negative += 1
words = msg.lower().split()
words_set = set(words)
for w in POSITIVE_WORDS:
parts = w.split()
if len(parts) > 1:
if CustomerHealthService._words_in_text(parts, words_set):
positive += 1
elif w in words_set:
positive += 1
for w in NEGATIVE_WORDS:
parts = w.split()
if len(parts) > 1:
if CustomerHealthService._words_in_text(parts, words_set):
negative += 1
elif w in words_set:
negative += 1
if positive > negative:
return {"score": 80, "label": "positive", "last_messages": messages}
elif negative > positive:
@@ -311,6 +328,24 @@ class CustomerHealthService:
return f"客户已沉默{silence_days}天,建议立即跟进,提供优惠或新产品信息"
return f"客户已沉默{silence_days}天,建议重新激活"
@staticmethod
def _calculate_overview_static(rows) -> Dict[str, Any]:
total = len(rows)
active = 0
watch = 0
critical = 0
for row in rows:
score = CustomerHealthService.calculate_silence_score(row.last_contact_at)
status_weight = CustomerHealthService.status_weight(row.status)
combined = score * 0.7 + status_weight * 0.3
if combined >= 70:
active += 1
elif combined >= 40:
watch += 1
else:
critical += 1
return {"total": total, "active": active, "watch": watch, "critical": critical}
def _calculate_silence_score(self, last_contact_at: Optional[datetime]) -> float:
return self.calculate_silence_score(last_contact_at)