feat: AI 摘要增加 8 位唯一识别码功能

- 生成 8 位唯一识别码(使用 0-9 和 A-Z,排除易混淆字符)

- 在摘要底部显示识别码

- 保存识别码到数据库(_argon_ai_summary_code)

- 添加反向查询 AJAX 接口(argon_query_ai_summary_by_code)

- 支持通过识别码查询文章信息、摘要内容、模型信息、生成时间
This commit is contained in:
2026-01-20 22:17:49 +08:00
parent 35bf3680b5
commit 0ff6cfce15
2 changed files with 171 additions and 68 deletions

View File

@@ -4217,7 +4217,7 @@ function shortcode_hidden($attr,$content=""){
}
$out .= "'";
if ($tip != ''){
$out .= " title='" . $tip ."'";
$out .= " title='" . esc_attr($tip) ."'";
}
$out .= ">" . $content . "</span>";
return $out;
@@ -6072,6 +6072,32 @@ add_action('argon_daily_link_check', 'argon_scheduled_link_check');
// ==================== AI 文章摘要功能 ====================
/**
* 生成 8 位唯一识别码
* @return string 8 位识别码
*/
function argon_generate_summary_code() {
$characters = '0123456789ABCDEFGHJKLMNPQRSTUVWXYZ'; // 去除易混淆字符 I, O
$code = '';
for ($i = 0; $i < 8; $i++) {
$code .= $characters[wp_rand(0, strlen($characters) - 1)];
}
// 检查是否已存在
global $wpdb;
$exists = $wpdb->get_var($wpdb->prepare(
"SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '_argon_ai_summary_code' AND meta_value = %s",
$code
));
// 如果存在,递归生成新的
if ($exists) {
return argon_generate_summary_code();
}
return $code;
}
/**
* 获取文章的 AI 摘要
* @param int $post_id 文章 ID
@@ -6483,11 +6509,19 @@ function argon_check_ai_summary() {
delete_transient('argon_ai_summary_generating_' . $post_id);
$model = get_post_meta($post_id, '_argon_ai_summary_model', true);
$provider = get_post_meta($post_id, '_argon_ai_summary_provider', true);
$code = get_post_meta($post_id, '_argon_ai_summary_code', true);
// 如果没有识别码,生成一个
if (empty($code)) {
$code = argon_generate_summary_code();
update_post_meta($post_id, '_argon_ai_summary_code', $code);
}
wp_send_json_success([
'summary' => esc_html($summary),
'model' => esc_html($model),
'provider' => esc_html($provider),
'code' => esc_html($code),
'generated' => true
]);
}
@@ -6508,12 +6542,16 @@ function argon_check_ai_summary() {
$provider = get_option('argon_ai_summary_provider', 'openai');
$model = get_option('argon_ai_summary_model', '');
// 生成唯一识别码
$summary_code = argon_generate_summary_code();
// 保存摘要和模型信息
update_post_meta($post_id, '_argon_ai_summary', $summary);
update_post_meta($post_id, '_argon_ai_summary_hash', $current_hash);
update_post_meta($post_id, '_argon_ai_summary_time', current_time('timestamp'));
update_post_meta($post_id, '_argon_ai_summary_model', $model);
update_post_meta($post_id, '_argon_ai_summary_provider', $provider);
update_post_meta($post_id, '_argon_ai_summary_code', $summary_code);
delete_transient('argon_ai_summary_generating_' . $post_id);
@@ -6521,6 +6559,7 @@ function argon_check_ai_summary() {
'summary' => esc_html($summary),
'model' => esc_html($model),
'provider' => esc_html($provider),
'code' => esc_html($summary_code),
'generated' => true
]);
} else {
@@ -6542,6 +6581,52 @@ function argon_check_ai_summary() {
add_action('wp_ajax_argon_check_ai_summary', 'argon_check_ai_summary');
add_action('wp_ajax_nopriv_argon_check_ai_summary', 'argon_check_ai_summary');
/**
* AJAX: 通过识别码查询 AI 摘要信息
*/
function argon_query_ai_summary_by_code() {
check_ajax_referer('argon_query_summary_code', 'nonce');
$code = sanitize_text_field($_POST['code']);
if (empty($code) || strlen($code) !== 8) {
wp_send_json_error(['message' => __('识别码格式无效', 'argon')]);
}
global $wpdb;
$post_id = $wpdb->get_var($wpdb->prepare(
"SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '_argon_ai_summary_code' AND meta_value = %s",
$code
));
if (!$post_id) {
wp_send_json_error(['message' => __('未找到对应的摘要记录', 'argon')]);
}
$post = get_post($post_id);
if (!$post) {
wp_send_json_error(['message' => __('文章不存在', 'argon')]);
}
$summary = get_post_meta($post_id, '_argon_ai_summary', true);
$model = get_post_meta($post_id, '_argon_ai_summary_model', true);
$provider = get_post_meta($post_id, '_argon_ai_summary_provider', true);
$time = get_post_meta($post_id, '_argon_ai_summary_time', true);
wp_send_json_success([
'post_id' => $post_id,
'post_title' => get_the_title($post_id),
'post_url' => get_permalink($post_id),
'summary' => esc_html($summary),
'model' => esc_html($model),
'provider' => esc_html($provider),
'generated_time' => $time ? date('Y-m-d H:i:s', $time) : '',
'code' => esc_html($code)
]);
}
add_action('wp_ajax_argon_query_ai_summary_by_code', 'argon_query_ai_summary_by_code');
add_action('wp_ajax_nopriv_argon_query_ai_summary_by_code', 'argon_query_ai_summary_by_code');
/**

View File

@@ -26,9 +26,10 @@ if (!empty($exclude_ids)) {
$summary = argon_get_ai_summary($post_id);
$is_generating = empty($summary);
// 获取模型信息
// 获取模型信息和识别码
$model = get_post_meta($post_id, '_argon_ai_summary_model', true);
$provider = get_post_meta($post_id, '_argon_ai_summary_provider', true);
$summary_code = get_post_meta($post_id, '_argon_ai_summary_code', true);
// 提供商名称映射
$provider_names = [
@@ -70,9 +71,14 @@ $model_display = !empty($model) ? $model : __('未知模型', 'argon');
</div>
<div class="ai-summary-footer">
<span class="ai-summary-disclaimer"><i class="fa fa-info-circle"></i> <?php _e('内容由AI生成请注意甄别', 'argon'); ?></span>
<?php if (!$is_generating && !empty($model)): ?>
<?php if (!$is_generating): ?>
<?php if (!empty($model)): ?>
<span class="ai-summary-model"><?php _e('使用模型', 'argon'); ?>: <?php echo esc_html($model_display); ?></span>
<?php endif; ?>
<?php if (!empty($summary_code)): ?>
<span class="ai-summary-code" title="<?php _e('文章识别码,可用于反向查询', 'argon'); ?>"><?php _e('识别码', 'argon'); ?>: <?php echo esc_html($summary_code); ?></span>
<?php endif; ?>
<?php endif; ?>
</div>
</div>
@@ -109,9 +115,15 @@ $model_display = !empty($model) ? $model : __('未知模型', 'argon');
if (contentDiv) {
contentDiv.innerHTML = '<p>' + data.data.summary + '</p>';
}
if (footerDiv && data.data.model) {
let modelInfo = '<span class="ai-summary-model"><?php _e('使用模型', 'argon'); ?>: ' + data.data.model + '</span>';
footerDiv.innerHTML = '<span class="ai-summary-disclaimer"><i class="fa fa-info-circle"></i> <?php _e('内容由AI生成请注意甄别', 'argon'); ?></span>' + modelInfo;
if (footerDiv) {
let footerHTML = '<span class="ai-summary-disclaimer"><i class="fa fa-info-circle"></i> <?php _e('内容由AI生成请注意甄别', 'argon'); ?></span>';
if (data.data.model) {
footerHTML += '<span class="ai-summary-model"><?php _e('使用模型', 'argon'); ?>: ' + data.data.model + '</span>';
}
if (data.data.code) {
footerHTML += '<span class="ai-summary-code" title="<?php _e('文章识别码,可用于反向查询', 'argon'); ?>"><?php _e('识别码', 'argon'); ?>: ' + data.data.code + '</span>';
}
footerDiv.innerHTML = footerHTML;
}
} else if (data.success === false) {
let loadingEl = document.querySelector('.ai-summary-loading');
@@ -196,6 +208,12 @@ $model_display = !empty($model) ? $model : __('未知模型', 'argon');
opacity: 0.6;
font-family: 'Consolas', 'Monaco', monospace;
}
.ai-summary-code {
opacity: 0.7;
font-family: 'Consolas', 'Monaco', monospace;
letter-spacing: 0.5px;
cursor: help;
}
.ai-summary-loading {
display: flex;
align-items: center;