小问题功能修复
This commit is contained in:
@@ -30,6 +30,6 @@ class UserFieldAiFill
|
|||||||
$job->delete();
|
$job->delete();
|
||||||
|
|
||||||
$delay = max(0, (int) (isset($data['delay']) ? $data['delay'] : 1));
|
$delay = max(0, (int) (isset($data['delay']) ? $data['delay'] : 1));
|
||||||
// $svc->enqueueNextFieldAi($delay, $queue, $userId, $force);
|
$svc->enqueueNextFieldAi($delay, $queue, $userId, $force);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -509,6 +509,24 @@ class PromotionService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 仅当模板真正引用了 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)
|
||||||
|
);
|
||||||
|
|
||||||
|
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)
|
// 一次 LLM 调用生成两段内容(description + advised_topics)
|
||||||
$llmResult = [
|
$llmResult = [
|
||||||
'description' => '',
|
'description' => '',
|
||||||
@@ -551,6 +569,7 @@ class PromotionService
|
|||||||
$expert['ai_advised_topics'] = $advisedText;
|
$expert['ai_advised_topics'] = $advisedText;
|
||||||
$expert['role'] = $this->mapExpertTypeRole($expertType);
|
$expert['role'] = $this->mapExpertTypeRole($expertType);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$expertVars = $this->buildExpertVars($expert);
|
$expertVars = $this->buildExpertVars($expert);
|
||||||
$journalVars = $this->buildJournalVars($journal);
|
$journalVars = $this->buildJournalVars($journal);
|
||||||
@@ -935,6 +954,73 @@ class PromotionService
|
|||||||
|
|
||||||
// ==================== Template Rendering ====================
|
// ==================== 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)
|
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();
|
$tpl = Db::name('mail_template')->where('template_id', $templateId)->where('journal_id', $journalId)->where('state', 0)->find();
|
||||||
|
|||||||
Reference in New Issue
Block a user