feat(ai): 打通 SEO 闭环与投稿写作辅助
对齐 Zibll 的 AI 生成 SEO 流程:统一 WP AI Client/主题 Provider 双后端、文章/分类 SEO 框与生成回填、投稿摘要/标签建议,并收敛扩展页为连接配置。
This commit is contained in:
@@ -13,6 +13,9 @@
|
||||
var i18n = (window.aksrtSubmitData && window.aksrtSubmitData.i18n) || {};
|
||||
var ajaxUrl = (window.aksrtSubmitData && window.aksrtSubmitData.ajaxUrl) || '/wp-admin/admin-ajax.php';
|
||||
var nonce = (window.aksrtSubmitData && window.aksrtSubmitData.nonce) || '';
|
||||
var restUrl = ((window.aksrtSubmitData && window.aksrtSubmitData.restUrl) || '/wp-json/aksrt/v1').replace(/\/$/, '');
|
||||
var restNonce = (window.aksrtSubmitData && window.aksrtSubmitData.restNonce) || '';
|
||||
var aiCfg = (window.aksrtSubmitData && window.aksrtSubmitData.ai) || {};
|
||||
|
||||
var FRONT_SUBMIT = {
|
||||
form: null,
|
||||
@@ -31,6 +34,7 @@
|
||||
this.bindCoverPreview();
|
||||
this.bindWordCount();
|
||||
this.bindLeaveWarning();
|
||||
this.bindAiAssist();
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -351,6 +355,112 @@
|
||||
contentEl.addEventListener('input', updateCount);
|
||||
updateCount();
|
||||
},
|
||||
|
||||
/**
|
||||
* AI 摘要 / 标签辅助(仅建议回填,不自动提交)
|
||||
*/
|
||||
bindAiAssist: function () {
|
||||
var self = this;
|
||||
if (!aiCfg.available) return;
|
||||
|
||||
var buttons = this.form.querySelectorAll('.aksrt-ai-assist-btn');
|
||||
if (!buttons.length) return;
|
||||
|
||||
buttons.forEach(function (btn) {
|
||||
btn.hidden = false;
|
||||
btn.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
var action = btn.getAttribute('data-ai-action');
|
||||
if (action === 'summary') self.runAiSummary(btn);
|
||||
if (action === 'tags') self.runAiTags(btn);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
getSubmitContent: function () {
|
||||
var titleEl = document.getElementById('submit-title');
|
||||
var contentEl = document.getElementById('submit-content');
|
||||
return {
|
||||
title: titleEl ? titleEl.value.trim() : '',
|
||||
content: contentEl ? contentEl.value.trim() : '',
|
||||
};
|
||||
},
|
||||
|
||||
runAiSummary: function (btn) {
|
||||
var data = this.getSubmitContent();
|
||||
if (!data.content) {
|
||||
alert(i18n.needContent || '请先填写正文内容');
|
||||
return;
|
||||
}
|
||||
this.aiRequest(btn, '/ai/summary-suggest', {
|
||||
title: data.title,
|
||||
content: data.content,
|
||||
max_length: 200,
|
||||
}, function (payload) {
|
||||
var summary = payload && payload.summary ? String(payload.summary) : '';
|
||||
var el = document.getElementById('submit-excerpt');
|
||||
if (el && summary) {
|
||||
el.value = summary;
|
||||
el.dispatchEvent(new Event('input', { bubbles: true }));
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
runAiTags: function (btn) {
|
||||
var data = this.getSubmitContent();
|
||||
if (!data.content && !data.title) {
|
||||
alert(i18n.needContent || '请先填写正文内容');
|
||||
return;
|
||||
}
|
||||
this.aiRequest(btn, '/ai/tags-suggest', {
|
||||
title: data.title,
|
||||
content: data.content,
|
||||
}, function (payload) {
|
||||
var tags = payload && Array.isArray(payload.tags) ? payload.tags : [];
|
||||
var el = document.getElementById('submit-tags');
|
||||
if (el && tags.length) {
|
||||
el.value = tags.join(', ');
|
||||
el.dispatchEvent(new Event('input', { bubbles: true }));
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
aiRequest: function (btn, path, body, onSuccess) {
|
||||
if (btn.getAttribute('data-loading') === '1') return;
|
||||
var original = btn.textContent;
|
||||
btn.setAttribute('data-loading', '1');
|
||||
btn.textContent = i18n.aiGenerating || '生成中…';
|
||||
|
||||
fetch(restUrl + path, {
|
||||
method: 'POST',
|
||||
credentials: 'same-origin',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-WP-Nonce': restNonce,
|
||||
},
|
||||
body: JSON.stringify(body || {}),
|
||||
})
|
||||
.then(function (r) {
|
||||
return r.json().then(function (json) {
|
||||
return { ok: r.ok, json: json };
|
||||
});
|
||||
})
|
||||
.then(function (res) {
|
||||
btn.removeAttribute('data-loading');
|
||||
btn.textContent = original;
|
||||
if (!res.ok || !res.json || res.json.success === false) {
|
||||
var msg = (res.json && res.json.message) || i18n.aiFailed || 'AI 生成失败';
|
||||
alert(msg);
|
||||
return;
|
||||
}
|
||||
onSuccess(res.json.data || {});
|
||||
})
|
||||
.catch(function () {
|
||||
btn.removeAttribute('data-loading');
|
||||
btn.textContent = original;
|
||||
alert(i18n.aiFailed || 'AI 生成失败');
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
|
||||
Reference in New Issue
Block a user