File: /www/wwwroot/www.byte123.top/wp-content/plugins/BoomStart/admin/class-bs-admin.php
<?php
/**
* 后台管理页面
*
* @package BoomStart
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
class BS_Admin
{
/**
* 初始化
*/
public static function init()
{
add_action('admin_menu', array(__CLASS__, 'register_menu'));
add_action('admin_enqueue_scripts', array(__CLASS__, 'enqueue_assets'));
}
/**
* 注册后台菜单
*/
public static function register_menu()
{
add_menu_page(
__('一键起站', 'boomstart'),
__('一键起站', 'boomstart'),
'manage_options',
'boomstart',
array(__CLASS__, 'render_page'),
'dashicons-star-filled',
30
);
}
/**
* 加载资源文件
*/
public static function enqueue_assets($hook)
{
// 仅在插件页面加载
if ('toplevel_page_boomstart' !== $hook) {
return;
}
wp_enqueue_style(
'bs-admin-css',
BS_URL . 'assets/css/bs-admin.css',
array(),
BS_VERSION
);
wp_enqueue_script(
'bs-admin-js',
BS_URL . 'assets/js/bs-admin.js',
array('jquery'),
BS_VERSION,
true
);
// 传递 AJAX 参数
wp_localize_script(
'bs-admin-js',
'bsAdmin',
array(
'ajaxUrl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('bs_action_nonce'),
'hasApiKey' => !empty(get_option('bs_api_key')) ? '1' : '0',
'i18n' => [
'emptyDescription' => __('请输入站点主题描述', 'boomstart'),
'selectCategory' => __('请选择分类', 'boomstart'),
'generating' => __('正在生成中...', 'boomstart'),
'generateBtn' => __('开始魔法生成', 'boomstart'),
'generateFailed' => __('生成失败,请重试', 'boomstart'),
'appending' => __('正在追加生成...', 'boomstart'),
'appendBtn' => __('开始追加生成', 'boomstart'),
'appendFailed' => __('追加生成失败,请重试', 'boomstart'),
'confirmPublish' => __('确定要发布所有草稿吗?发布后无法通过本插件批量撤回。', 'boomstart'),
'publishing' => __('发布中...', 'boomstart'),
'publishFailed' => __('发布失败,请重试', 'boomstart'),
'networkError' => __('网络错误,请检查连接后重试', 'boomstart'),
'confirmDelete' => __('确定要删除所有生成的分类和文章吗?\n它们将被移至回收站,可在 WordPress 回收站中恢复。', 'boomstart'),
'deleting' => __('删除中...', 'boomstart'),
'deleteFailed' => __('删除失败,请重试', 'boomstart'),
'deleteSuccess' => __('已删除,页面即将刷新', 'boomstart'),
'saving' => __('保存中...', 'boomstart'),
'saved' => __('✅ 已保存', 'boomstart'),
'saveFailed' => __('保存失败,请重试', 'boomstart'),
'testing' => __('测试中...', 'boomstart'),
'testSuccess' => __('✅ 连接成功,模型响应正常', 'boomstart'),
'testFailed' => __('❌ 连接失败:', 'boomstart'),
'aiThinking' => __('AI 正在思考中,请稍候...', 'boomstart'),
'taskExpired' => __('任务已过期,请重新生成', 'boomstart'),
'generatingElapsed' => __('已等待 %s 秒...', 'boomstart'),
'generateTimeout' => __('生成超时,请重试', 'boomstart'),
'useMockNotice' => __('你尚未配置 API Key,无法使用 AI 生成。\n你可以先配置 API Key,或使用测试数据体验功能(内容为固定示例,非 AI 生成)。', 'boomstart'),
'useMockData' => __('使用测试数据', 'boomstart'),
'goSettings' => __('去配置 API Key', 'boomstart'),
'stageThinking' => __('⏳ 正在思考站点主题...', 'boomstart'),
'stageCategories' => __('📂 正在创建分类...', 'boomstart'),
'stageWriting' => __('✍️ 正在撰写文章内容...', 'boomstart'),
'stageImages' => __('🖼️ 正在下载本地配图...', 'boomstart'),
'stageDone' => __('✅ 全部处理完成!', 'boomstart'),
'optionsSaved' => __('✅ 选项已保存', 'boomstart'),
'optionsSaving' => __('保存中...', 'boomstart'),
],
)
);
}
/**
* 渲染管理页面
*/
public static function render_page()
{
// 权限校验
if (!current_user_can('manage_options')) {
wp_die(esc_html__('您没有权限访问此页面。', 'boomstart'));
}
$stats = BS_Cleaner::get_generated_stats();
$has_content = ($stats['drafts'] > 0 || $stats['published'] > 0 || $stats['terms'] > 0);
?>
<div class="wrap bs-wrap">
<h1><?php esc_html_e('一键起站', 'boomstart'); ?></h1>
<?php self::render_settings_card(); ?>
<?php self::render_generation_options_card(); ?>
<?php if ($has_content): ?>
<?php self::render_action_card($stats); ?>
<?php
else: ?>
<?php self::render_input_view(); ?>
<?php
endif; ?>
</div>
<?php
}
/**
* 渲染 API 设置卡片
*/
private static function render_settings_card()
{
$api_key = get_option('bs_api_key', '');
$has_api_key = !empty($api_key);
$collapsed_class = $has_api_key ? 'collapsed' : '';
$badge = $has_api_key
? '<span class="bs-badge-ok">✅ ' . esc_html__('已配置', 'boomstart') . '</span>'
: '<span class="bs-badge-warn">⚠️ ' . esc_html__('未配置', 'boomstart') . '</span>';
?>
<div class="bs-card bs-settings-card <?php echo esc_attr($collapsed_class); ?>">
<div class="bs-settings-header">
<span>
<?php esc_html_e('⚙️ API 设置', 'boomstart'); ?>
<?php echo $badge; ?>
</span>
<span class="bs-settings-arrow">▾</span>
</div>
<div class="bs-settings-body">
<div class="bs-form-group">
<label for="bs-api-base-url"><?php esc_html_e('Base URL', 'boomstart'); ?></label>
<input type="text" id="bs-api-base-url" class="bs-textarea"
value="<?php echo esc_attr(get_option('bs_api_base_url', '')); ?>"
placeholder="https://api.deepseek.com/v1">
</div>
<div class="bs-form-group">
<label for="bs-api-key"><?php esc_html_e('API Key', 'boomstart'); ?></label>
<input type="password" id="bs-api-key" class="bs-textarea"
value="<?php echo esc_attr($api_key); ?>"
placeholder="sk-...">
</div>
<div class="bs-form-group">
<label for="bs-api-model"><?php esc_html_e('Model', 'boomstart'); ?></label>
<input type="text" id="bs-api-model" class="bs-textarea"
value="<?php echo esc_attr(get_option('bs_api_model', '')); ?>"
placeholder="deepseek-chat">
</div>
<div class="bs-form-group">
<label>
<input type="checkbox" id="bs-enable-images"
<?php checked(get_option('bs_enable_images', 0), 1); ?>>
<?php esc_html_e('自动配图(为文章下载特色图片)', 'boomstart'); ?>
</label>
<p class="bs-settings-note">
<?php esc_html_e('开启后会根据文章标题自动下载免费图片到媒体库,可能增加生成时间', 'boomstart'); ?>
</p>
</div>
<div class="bs-form-actions">
<button id="bs-btn-save-settings" class="button button-secondary">
<?php esc_html_e('保存设置', 'boomstart'); ?>
</button>
<button id="bs-btn-test-api" class="button button-secondary">
<?php esc_html_e('🔗 测试连接', 'boomstart'); ?>
</button>
<span id="bs-test-result" style="margin-left: 8px;"></span>
</div>
<p class="bs-settings-note">
<?php esc_html_e('支持 Deepseek、OpenAI 等兼容 OpenAI API 格式的 AI 服务', 'boomstart'); ?>
</p>
</div>
</div>
<?php
}
/**
* 渲染生成选项卡片
*/
private static function render_generation_options_card()
{
$word_count = get_option('bs_word_count', 'standard');
$tone = get_option('bs_tone', 'professional');
?>
<div class="bs-card bs-options-card">
<div class="bs-options-header">
<span><?php esc_html_e('📝 生成选项', 'boomstart'); ?></span>
</div>
<div class="bs-options-body">
<div class="bs-options-row">
<div class="bs-form-group bs-form-inline">
<label for="bs-word-count"><?php esc_html_e('文章篇幅', 'boomstart'); ?></label>
<select id="bs-word-count" class="bs-select">
<option value="brief" <?php selected($word_count, 'brief'); ?>><?php esc_html_e('简洁(约200字)', 'boomstart'); ?></option>
<option value="standard" <?php selected($word_count, 'standard'); ?>><?php esc_html_e('标准(约300字)', 'boomstart'); ?></option>
<option value="rich" <?php selected($word_count, 'rich'); ?>><?php esc_html_e('丰富(约500字)', 'boomstart'); ?></option>
</select>
</div>
<div class="bs-form-group bs-form-inline">
<label for="bs-tone"><?php esc_html_e('写作风格', 'boomstart'); ?></label>
<select id="bs-tone" class="bs-select">
<option value="professional" <?php selected($tone, 'professional'); ?>><?php esc_html_e('专业正式', 'boomstart'); ?></option>
<option value="friendly" <?php selected($tone, 'friendly'); ?>><?php esc_html_e('亲切随和', 'boomstart'); ?></option>
<option value="seo" <?php selected($tone, 'seo'); ?>><?php esc_html_e('SEO 优化', 'boomstart'); ?></option>
</select>
</div>
<button id="bs-btn-save-options" class="button button-small">
<?php esc_html_e('保存选项', 'boomstart'); ?>
</button>
<span id="bs-options-result" style="margin-left: 8px;"></span>
</div>
</div>
</div>
<?php
}
/**
* 渲染输入表单视图
*/
private static function render_input_view()
{
?>
<div class="bs-card">
<p class="bs-intro">
<?php esc_html_e('只需简单描述你的站点主题,我们就能为你生成精心设计的分类和文章草稿。', 'boomstart'); ?>
</p>
<form id="bs-generate-form" class="bs-form">
<div class="bs-form-group">
<label for="bs-site-description"><?php esc_html_e('站点主题描述', 'boomstart'); ?></label>
<textarea id="bs-site-description" name="site_description" rows="5" class="bs-textarea" required
placeholder="<?php esc_attr_e('例如:一个关于健康饮食和营养知识的博客...', 'boomstart'); ?>"></textarea>
</div>
<div class="bs-form-actions">
<button type="submit" class="button button-primary button-hero bs-btn-generate">
<?php esc_html_e('开始魔法生成', 'boomstart'); ?>
</button>
</div>
</form>
<div id="bs-result" style="display:none;"><div class="bs-result-content"></div></div>
</div>
<?php
}
/**
* 渲染行动卡片视图
*
* @param array $stats 统计信息
*/
private static function render_action_card($stats)
{
?>
<div class="bs-card">
<p class="bs-stats-summary">
<?php printf(
esc_html__('✅ 已为你生成 %1$d 个分类、%2$d 篇草稿、%3$d 篇已发布', 'boomstart'),
(int)$stats['terms'],
(int)$stats['drafts'],
(int)$stats['published']
); ?>
</p>
<div class="bs-action-row">
<?php if ($stats['drafts'] > 0): ?>
<button id="bs-btn-publish-all" class="button button-primary">
<?php printf(esc_html__('一键发布全部草稿(%d篇)', 'boomstart'), (int)$stats['drafts']); ?>
</button>
<?php
else: ?>
<button class="button" disabled><?php esc_html_e('✓ 已全部发布', 'boomstart'); ?></button>
<?php
endif; ?>
<button id="bs-btn-add-more" class="button button-secondary">
<?php esc_html_e('✨ 继续追加生成', 'boomstart'); ?>
</button>
<a href="<?php echo esc_url(admin_url('edit.php')); ?>" class="bs-link">
<?php esc_html_e('查看文章 ↗', 'boomstart'); ?>
</a>
<a href="<?php echo esc_url(admin_url('edit-tags.php?taxonomy=category')); ?>" class="bs-link">
<?php esc_html_e('查看分类 ↗', 'boomstart'); ?>
</a>
<button id="bs-btn-delete-all" class="button bs-btn-danger">
<?php esc_html_e('🗑️ 删除所有生成内容', 'boomstart'); ?>
</button>
</div>
<div id="bs-append-form-wrap" style="display:none;" class="bs-append-form-wrap">
<div class="bs-form-group">
<label for="bs-category-id"><?php esc_html_e('选择分类', 'boomstart'); ?></label>
<?php wp_dropdown_categories([
'show_option_none' => __('请选择分类', 'boomstart'),
'option_none_value' => '0',
'name' => 'bs_category_id',
'id' => 'bs-category-id',
'hide_empty' => false,
'class' => 'bs-select',
]); ?>
</div>
<div class="bs-form-group">
<label for="bs-append-description"><?php esc_html_e('站点主题描述', 'boomstart'); ?></label>
<textarea id="bs-append-description" rows="3" class="bs-textarea"
placeholder="<?php esc_attr_e('可修改描述以生成不同风格的内容...', 'boomstart'); ?>"></textarea>
</div>
<div class="bs-form-actions">
<button id="bs-btn-append-submit" class="button button-primary">
<?php esc_html_e('开始追加生成', 'boomstart'); ?>
</button>
<button id="bs-btn-cancel-append" class="button">
<?php esc_html_e('取消', 'boomstart'); ?>
</button>
</div>
<div id="bs-append-result" style="display:none;"><div class="bs-append-result-content"></div></div>
</div>
</div>
<?php
}
}