小问题功能修复
This commit is contained in:
@@ -30,6 +30,6 @@ class UserFieldAiFill
|
||||
$job->delete();
|
||||
|
||||
$delay = max(0, (int) (isset($data['delay']) ? $data['delay'] : 1));
|
||||
// $svc->enqueueNextFieldAi($delay, $queue, $userId, $force);
|
||||
$svc->enqueueNextFieldAi($delay, $queue, $userId, $force);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -509,47 +509,66 @@ class PromotionService
|
||||
}
|
||||
}
|
||||
|
||||
// 一次 LLM 调用生成两段内容(description + advised_topics)
|
||||
$llmResult = [
|
||||
'description' => '',
|
||||
'description_status' => 0,
|
||||
'advised_topics' => '',
|
||||
'advised_topics_status' => 0,
|
||||
];
|
||||
try {
|
||||
$llm = new PromotionLlmService();
|
||||
$llmResult = $llm->generateEmailContent(
|
||||
$expert,
|
||||
$journal ?: [],
|
||||
$overlapFields,
|
||||
$taskFields,
|
||||
$fieldSet
|
||||
);
|
||||
} catch (\Exception $e) {
|
||||
$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['description'];
|
||||
$llmStatus = intval($llmResult['description_status']);
|
||||
$advisedText = (string)$llmResult['advised_topics'];
|
||||
$advisedStatus = intval($llmResult['advised_topics_status']);
|
||||
// 仅当模板真正引用了 LLM 占位符(llm_description / ai_content_analysis /
|
||||
// ai_advised_topics / llm_advised_topics)时才调用 LLM,避免无谓的请求与开销。
|
||||
$llmNeed = $this->detectLlmTemplateNeed(
|
||||
$task['template_id'],
|
||||
$task['journal_id'],
|
||||
intval($task['style_id'] ?? 0)
|
||||
);
|
||||
|
||||
$expert['llm_description'] = $llmText;
|
||||
$expert['ai_advised_topics'] = $advisedText;
|
||||
$expert['role'] = $this->mapExpertTypeRole($expertType);
|
||||
if (!$llmNeed['need']) {
|
||||
$llmText = '';
|
||||
$llmStatus = 0;
|
||||
$advisedText = '';
|
||||
$advisedStatus = 0;
|
||||
$expert['llm_description'] = '';
|
||||
$expert['ai_advised_topics'] = '';
|
||||
$expert['role'] = $this->mapExpertTypeRole($expertType);
|
||||
$this->log("prepareSingleEmail log_id={$logId} skip_llm (template has no llm placeholders)");
|
||||
} else {
|
||||
// 一次 LLM 调用生成两段内容(description + advised_topics)
|
||||
$llmResult = [
|
||||
'description' => '',
|
||||
'description_status' => 0,
|
||||
'advised_topics' => '',
|
||||
'advised_topics_status' => 0,
|
||||
];
|
||||
try {
|
||||
$llm = new PromotionLlmService();
|
||||
$llmResult = $llm->generateEmailContent(
|
||||
$expert,
|
||||
$journal ?: [],
|
||||
$overlapFields,
|
||||
$taskFields,
|
||||
$fieldSet
|
||||
);
|
||||
} catch (\Exception $e) {
|
||||
$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['description'];
|
||||
$llmStatus = intval($llmResult['description_status']);
|
||||
$advisedText = (string)$llmResult['advised_topics'];
|
||||
$advisedStatus = intval($llmResult['advised_topics_status']);
|
||||
|
||||
$expert['llm_description'] = $llmText;
|
||||
$expert['ai_advised_topics'] = $advisedText;
|
||||
$expert['role'] = $this->mapExpertTypeRole($expertType);
|
||||
}
|
||||
}
|
||||
|
||||
$expertVars = $this->buildExpertVars($expert);
|
||||
@@ -935,6 +954,73 @@ class PromotionService
|
||||
|
||||
// ==================== Template Rendering ====================
|
||||
|
||||
/**
|
||||
* 检测邮件模板(含 style 头尾)是否包含需要 LLM 生成的占位符。
|
||||
*
|
||||
* @return array{need:bool,need_description:bool,need_advised_topics:bool,tags:array<int,string>}
|
||||
*/
|
||||
public function detectLlmTemplateNeed($templateId, $journalId, $styleId = 0)
|
||||
{
|
||||
$descriptionTags = ['llm_description', 'ai_content_analysis'];
|
||||
$advisedTags = ['ai_advised_topics', 'llm_advised_topics'];
|
||||
$allTags = array_merge($descriptionTags, $advisedTags);
|
||||
|
||||
$parts = [];
|
||||
$tpl = Db::name('mail_template')
|
||||
->where('template_id', $templateId)
|
||||
->where('journal_id', $journalId)
|
||||
->where('state', 0)
|
||||
->find();
|
||||
if ($tpl) {
|
||||
$parts[] = (string)($tpl['subject'] ?? '');
|
||||
$parts[] = (string)($tpl['body_html'] ?? '');
|
||||
}
|
||||
$styleId = intval($styleId);
|
||||
if ($styleId > 0) {
|
||||
$style = Db::name('mail_style')->where('style_id', $styleId)->where('state', 0)->find();
|
||||
if ($style) {
|
||||
$parts[] = (string)($style['header_html'] ?? '');
|
||||
$parts[] = (string)($style['footer_html'] ?? '');
|
||||
}
|
||||
}
|
||||
|
||||
$haystack = implode("\n", $parts);
|
||||
$found = [];
|
||||
foreach ($allTags as $tag) {
|
||||
if ($this->templateContainsVar($haystack, $tag)) {
|
||||
$found[] = $tag;
|
||||
}
|
||||
}
|
||||
|
||||
$needDesc = (bool) array_intersect($found, $descriptionTags);
|
||||
$needAdvised = (bool) array_intersect($found, $advisedTags);
|
||||
|
||||
return [
|
||||
'need' => !empty($found),
|
||||
'need_description' => $needDesc,
|
||||
'need_advised_topics' => $needAdvised,
|
||||
'tags' => $found,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 模板是否包含某变量占位符(支持 {{ var }} 与 {var})。
|
||||
*/
|
||||
protected function templateContainsVar($haystack, $varName)
|
||||
{
|
||||
if (!is_string($haystack) || $haystack === '' || $varName === '') {
|
||||
return false;
|
||||
}
|
||||
$quoted = preg_quote($varName, '/');
|
||||
if (preg_match('/\{\{\s*' . $quoted . '\s*\}\}/', $haystack)) {
|
||||
return true;
|
||||
}
|
||||
if (strpos($haystack, '{' . $varName . '}') !== false) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function renderFromTemplate($templateId, $journalId, $varsJson, $styleId = 0)
|
||||
{
|
||||
$tpl = Db::name('mail_template')->where('template_id', $templateId)->where('journal_id', $journalId)->where('state', 0)->find();
|
||||
|
||||
Reference in New Issue
Block a user