ID, self::META_TITLE, true); $keywords = (string) get_post_meta($post->ID, self::META_KEYWORDS, true); $description = (string) get_post_meta($post->ID, self::META_DESCRIPTION, true); $ai_btn = $this->render_ai_button('post', (int) $post->ID); $summary_btn = $this->render_summary_button((int) $post->ID); ?>

'aksrt_seo_title', self::META_KEYWORDS => 'aksrt_seo_keywords', self::META_DESCRIPTION => 'aksrt_seo_description', ]; foreach ($map as $meta_key => $field) { if (!isset($_POST[$field])) { continue; } $value = sanitize_text_field(wp_unslash((string) $_POST[$field])); if ($value === '') { delete_post_meta($post_id, $meta_key); } else { update_post_meta($post_id, $meta_key, $value); } } } /** * @param \WP_Term $term */ public function render_term_fields($term): void { if (!$term instanceof \WP_Term) { return; } $title = (string) get_term_meta($term->term_id, self::META_TITLE, true); $keywords = (string) get_term_meta($term->term_id, self::META_KEYWORDS, true); $description = (string) get_term_meta($term->term_id, self::META_DESCRIPTION, true); $ai_btn = $this->render_ai_button('term', (int) $term->term_id); ?>

'aksrt_seo_title', self::META_KEYWORDS => 'aksrt_seo_keywords', self::META_DESCRIPTION => 'aksrt_seo_description', ]; foreach ($map as $meta_key => $field) { if (!isset($_POST[$field])) { continue; } $value = sanitize_text_field(wp_unslash((string) $_POST[$field])); if ($value === '') { delete_term_meta($term_id, $meta_key); } else { update_term_meta($term_id, $meta_key, $value); } } } public function enqueue_assets(string $hook): void { $screen = function_exists('get_current_screen') ? get_current_screen() : null; if (!$screen) { return; } $ok = in_array($screen->base, ['post', 'term', 'edit-tags'], true); if (!$ok) { return; } $path = AKSRT_DIR . '/assets/js/admin-ai-seo.js'; if (!is_file($path)) { return; } wp_enqueue_script( 'aksrt-admin-ai-seo', AKSRT_URI . '/assets/js/admin-ai-seo.js', [], (string) filemtime($path), true ); $status = class_exists('\AKSRT\Ai\AI') ? \AKSRT\Ai\AI::get_instance()->get_status() : []; $seo = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::get_seo_settings() : []; wp_localize_script('aksrt-admin-ai-seo', 'aksrtAiSeo', [ 'restUrl' => esc_url_raw(rest_url('aksrt/v1')), 'nonce' => wp_create_nonce('wp_rest'), 'ai' => [ 'available' => !empty($status['available']), 'seo_ai_enabled' => !empty($seo['seo_ai_enabled']) && !empty($seo['seo_enabled']), 'write_assist' => !empty($status['available']), ], 'i18n' => [ 'generating' => __('生成中…', 'aksrt'), 'generate' => __('AI 生成 SEO', 'aksrt'), 'generateSummary' => __('AI 生成摘要', 'aksrt'), 'success' => __('已填入 SEO 字段,请检查后更新保存', 'aksrt'), 'summarySuccess' => __('已填入摘要字段,请检查后更新保存', 'aksrt'), 'failed' => __('生成失败', 'aksrt'), 'needSave' => __('请先保存后再生成 SEO', 'aksrt'), 'needContent' => __('请先填写正文内容', 'aksrt'), 'notAvailable' => __('AI 未配置或未启用', 'aksrt'), 'noExcerptField' => __('未找到摘要字段,请展开「摘要」面板', 'aksrt'), ], ]); wp_add_inline_style('wp-admin', ' .aksrt-ai-seo-button{display:inline-block;margin-left:8px;vertical-align:middle} .aksrt-ai-seo-generate,.aksrt-ai-summary-generate{cursor:pointer} .aksrt-ai-seo-generate.is-loading,.aksrt-ai-summary-generate.is-loading{opacity:.6;pointer-events:none} .aksrt-ai-seo-msg{display:block;margin-top:6px;font-size:12px} .aksrt-ai-seo-msg.is-error{color:#b32d2e} .aksrt-ai-seo-msg.is-ok{color:#007017} .aksrt-ai-summary-row{margin-top:8px;padding-top:8px;border-top:1px solid #eee} '); } private function render_ai_button(string $type, int $id): string { $seo = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::get_seo_settings() : []; if (empty($seo['seo_enabled']) || empty($seo['seo_ai_enabled'])) { return ''; } $available = class_exists('\AKSRT\Ai\AI') && \AKSRT\Ai\AI::get_instance()->is_available(); $disabled = (!$available || $id <= 0) ? ' disabled' : ''; $title = !$available ? esc_attr__('请先配置 AI 连接(扩展 → AI 连接配置 或 WP Connectors)', 'aksrt') : ($id <= 0 ? esc_attr__('请先保存后再生成', 'aksrt') : ''); return sprintf( '', $disabled, esc_attr($type), $id, $title, esc_html__('AI 生成 SEO', 'aksrt') ); } /** * 后台「AI 生成摘要」→ 写入 WP 摘要字段(#excerpt / 块编辑器)。 */ private function render_summary_button(int $post_id): string { $available = class_exists('\AKSRT\Ai\AI') && \AKSRT\Ai\AI::get_instance()->is_available(); if (!$available) { return ''; } $disabled = $post_id <= 0 ? ' disabled' : ''; $title = $post_id <= 0 ? esc_attr__('请先保存后再生成', 'aksrt') : esc_attr__('根据正文生成摘要,填入摘要框', 'aksrt'); return sprintf( '', $disabled, $post_id, $title, esc_html__('AI 生成摘要', 'aksrt') ); } }