修改自动推广的相关任务

This commit is contained in:
wangjinlei
2026-04-24 14:50:16 +08:00
parent 7a204961de
commit 13fd3af816
4 changed files with 285 additions and 62 deletions

View File

@@ -123,6 +123,17 @@ class PromotionService
}
$expert['fields'] = implode(',', $fieldSet);
$expert['representative_work_title'] = $matchedTitle !== '' ? $matchedTitle : $fallbackTitle;
// 现场发送路径:没有提前准备 LLM退回 .env 兜底文案
try {
$llmSvc = new PromotionLlmService();
$expert['llm_description'] = $llmSvc->getFallback();
$expert['ai_advised_topics'] = $llmSvc->getAdvisedFallback();
} catch (\Exception $e) {
$expert['llm_description'] = '';
$expert['ai_advised_topics'] = '';
}
$expertVars = $this->buildExpertVars($expert);
$journalVars = $this->buildJournalVars($journal);
$vars = array_merge($journalVars, $expertVars);
@@ -312,21 +323,60 @@ class PromotionService
$expert['fields'] = implode(',', $fieldSet);
$expert['representative_work_title'] = $matchedTitle !== '' ? $matchedTitle : $fallbackTitle;
// 领域交集(大小写不敏感,保留 expert 原字面值用于展示)
$overlapFields = [];
if (!empty($taskFieldLower)) {
foreach ($fieldSet as $fn) {
if (isset($taskFieldLower[strtolower($fn)])) {
$overlapFields[] = $fn;
}
}
}
$journal = Db::name('journal')->where('journal_id', $task['journal_id'])->find();
// 调用 LLM 生成个性化描述(失败/缺条件时回退到兜底文案
$llmResult = ['status' => 0, 'text' => ''];
// 一次 LLM 调用生成两段内容description + advised_topics
$llmResult = [
'description' => '',
'description_status' => 0,
'advised_topics' => '',
'advised_topics_status' => 0,
];
try {
$llm = new PromotionLlmService();
$llmResult = $llm->generateDescription($expert, $journal ?: []);
$llmResult = $llm->generateEmailContent(
$expert,
$journal ?: [],
$overlapFields,
$taskFields,
$fieldSet
);
} catch (\Exception $e) {
$llmResult = ['status' => 2, 'text' => ''];
// 兜底双占位($llm 实例可能未成功构建,单独拿一个尝试)
$fbDesc = '';
$fbAdvised = '';
try {
$fbSvc = isset($llm) ? $llm : new PromotionLlmService();
$fbDesc = $fbSvc->getFallback();
$fbAdvised = $fbSvc->getAdvisedFallback();
} catch (\Exception $ignore) {
// 忽略,使用空串
}
$llmResult = [
'description' => $fbDesc,
'description_status' => 2,
'advised_topics' => $fbAdvised,
'advised_topics_status' => 2,
];
$this->log("prepareSingleEmail log_id={$logId} llm_exception=" . $e->getMessage());
}
$llmText = (string)$llmResult['text'];
$llmStatus = intval($llmResult['status']);
$llmText = (string)$llmResult['description'];
$llmStatus = intval($llmResult['description_status']);
$advisedText = (string)$llmResult['advised_topics'];
$advisedStatus = intval($llmResult['advised_topics_status']);
$expert['llm_description'] = $llmText;
$expert['llm_description'] = $llmText;
$expert['ai_advised_topics'] = $advisedText;
$expertVars = $this->buildExpertVars($expert);
$journalVars = $this->buildJournalVars($journal);
@@ -341,27 +391,41 @@ class PromotionService
$now = time();
if ($rendered['code'] !== 0) {
Db::name('promotion_email_log')->where('log_id', $logId)->update([
'state' => 2,
'error_msg' => 'Prepare failed: ' . $rendered['msg'],
'llm_description' => mb_substr($llmText, 0, 2000),
'llm_status' => $llmStatus,
'send_time' => $now,
'state' => 2,
'error_msg' => 'Prepare failed: ' . $rendered['msg'],
'llm_description' => mb_substr($llmText, 0, 2000),
'llm_status' => $llmStatus,
'llm_advised_topics' => mb_substr($advisedText, 0, 2000),
'llm_advised_topics_status' => $advisedStatus,
'send_time' => $now,
]);
$this->tryFinalizeTask($task['task_id']);
return ['code' => 1, 'msg' => $rendered['msg'], 'llm_status' => $llmStatus];
return [
'code' => 1,
'msg' => $rendered['msg'],
'llm_status' => $llmStatus,
'llm_advised_topics_status' => $advisedStatus,
];
}
Db::name('promotion_email_log')->where('log_id', $logId)->update([
'subject_prepared' => mb_substr($rendered['data']['subject'], 0, 512),
'body_prepared' => $rendered['data']['body'],
'llm_description' => mb_substr($llmText, 0, 2000),
'llm_status' => $llmStatus,
'prepared_at' => $now,
'subject_prepared' => mb_substr($rendered['data']['subject'], 0, 512),
'body_prepared' => $rendered['data']['body'],
'llm_description' => mb_substr($llmText, 0, 2000),
'llm_status' => $llmStatus,
'llm_advised_topics' => mb_substr($advisedText, 0, 2000),
'llm_advised_topics_status' => $advisedStatus,
'prepared_at' => $now,
]);
$this->tryFinalizeTask($task['task_id']);
return ['code' => 0, 'msg' => 'ok', 'llm_status' => $llmStatus];
return [
'code' => 0,
'msg' => 'ok',
'llm_status' => $llmStatus,
'llm_advised_topics_status' => $advisedStatus,
];
}
/**
@@ -725,16 +789,19 @@ class PromotionService
public function buildExpertVars($expert)
{
$llm = $expert['llm_description'] ?? '';
$llm = $expert['llm_description'] ?? '';
$advised = $expert['ai_advised_topics'] ?? '';
return [
'expert_title' => "Ph.D",
'expert_name' => $expert['name'] ?? '',
'expert_email' => $expert['email'] ?? '',
'expert_affiliation' => $expert['affiliation'] ?? '',
'expert_field' => $expert['fields'] ?? ($expert['field'] ?? ''),
'expert_title' => "Ph.D",
'expert_name' => $expert['name'] ?? '',
'expert_email' => $expert['email'] ?? '',
'expert_affiliation' => $expert['affiliation'] ?? '',
'expert_field' => $expert['fields'] ?? ($expert['field'] ?? ''),
'representative_work_title' => $expert['representative_work_title'] ?? '',
'llm_description' => $llm,
'ai_content_analysis' => $llm,
'llm_description' => $llm,
'ai_content_analysis' => $llm,
'ai_advised_topics' => $advised,
'llm_advised_topics' => $advised,
];
}