文章目录[隐藏]
实战教程:在WordPress网站中添加在线个人健康数据记录与趋势分析小程序
摘要
本教程将详细介绍如何在WordPress网站中通过代码二次开发,实现一个功能完整的在线个人健康数据记录与趋势分析小程序。我们将从需求分析、数据库设计、前端界面开发、后端数据处理到数据可视化展示,一步步构建一个实用的健康管理工具。本教程适合有一定WordPress开发基础的开发者,通过约5000字的详细讲解,帮助您掌握在WordPress中集成自定义功能的完整流程。
目录
- 项目概述与需求分析
- 环境准备与WordPress开发基础
- 数据库设计与数据表创建
- 用户界面设计与前端开发
- 后端数据处理与API开发
- 数据可视化与趋势分析实现
- 安全性与数据隐私保护
- 测试、优化与部署
- 功能扩展与未来改进方向
1. 项目概述与需求分析
1.1 项目背景
随着健康意识的提升,越来越多的人希望系统性地记录和分析自己的健康数据。然而,市面上的健康管理应用往往存在数据隐私担忧、功能过于复杂或缺乏定制化等问题。通过在个人或企业WordPress网站中集成健康数据记录与分析功能,用户可以完全控制自己的数据,同时获得个性化的健康管理体验。
1.2 核心功能需求
- 用户认证与权限管理:确保用户只能访问自己的健康数据
- 健康数据录入:支持多种数据类型(体重、血压、血糖、运动量等)
- 数据存储与管理:安全可靠的数据库存储与检索
- 数据可视化:图表展示健康数据变化趋势
- 趋势分析与报告:基于历史数据的智能分析
- 数据导出:支持CSV、PDF等格式导出
- 移动端适配:确保在手机和平板上良好显示
1.3 技术选型
- 核心平台:WordPress 5.8+
- 前端技术:HTML5、CSS3、JavaScript (jQuery/Vue.js可选)
- 图表库:Chart.js 或 Google Charts
- 数据库:MySQL (WordPress默认)
- 开发方式:WordPress插件开发模式
2. 环境准备与WordPress开发基础
2.1 开发环境搭建
- 安装本地开发环境(推荐XAMPP、MAMP或Local by Flywheel)
- 下载最新版WordPress并完成安装
-
配置调试模式,在wp-config.php中添加:
define('WP_DEBUG', true); define('WP_DEBUG_LOG', true); define('WP_DEBUG_DISPLAY', false);
2.2 WordPress插件开发基础
我们将以插件形式开发健康管理功能,确保与主题的兼容性和可移植性。
创建插件基本结构:
wp-content/plugins/health-tracker/
├── health-tracker.php // 主插件文件
├── includes/ // 包含文件目录
│ ├── class-database.php // 数据库处理类
│ ├── class-shortcodes.php // 短码处理类
│ ├── class-api.php // API处理类
│ └── class-analysis.php // 数据分析类
├── admin/ // 后台管理文件
├── public/ // 前端文件
│ ├── css/ // 样式文件
│ ├── js/ // JavaScript文件
│ └── templates/ // 前端模板
└── assets/ // 静态资源
2.3 插件主文件结构
创建health-tracker.php作为插件入口:
<?php
/**
* Plugin Name: 个人健康数据记录与分析
* Plugin URI: https://yourwebsite.com/health-tracker
* Description: 在WordPress网站中添加个人健康数据记录与趋势分析功能
* Version: 1.0.0
* Author: 您的名称
* License: GPL v2 or later
* Text Domain: health-tracker
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('HEALTH_TRACKER_VERSION', '1.0.0');
define('HEALTH_TRACKER_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('HEALTH_TRACKER_PLUGIN_URL', plugin_dir_url(__FILE__));
// 初始化插件
require_once HEALTH_TRACKER_PLUGIN_DIR . 'includes/class-database.php';
require_once HEALTH_TRACKER_PLUGIN_DIR . 'includes/class-shortcodes.php';
require_once HEALTH_TRACKER_PLUGIN_DIR . 'includes/class-api.php';
require_once HEALTH_TRACKER_PLUGIN_DIR . 'includes/class-analysis.php';
class Health_Tracker {
private static $instance = null;
public static function get_instance() {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
$this->init_hooks();
}
private function init_hooks() {
// 激活/停用钩子
register_activation_hook(__FILE__, array($this, 'activate'));
register_deactivation_hook(__FILE__, array($this, 'deactivate'));
// 初始化组件
add_action('init', array($this, 'init'));
// 加载文本域
add_action('plugins_loaded', array($this, 'load_textdomain'));
}
public function activate() {
// 创建数据库表
Health_Tracker_Database::create_tables();
// 设置默认选项
update_option('health_tracker_version', HEALTH_TRACKER_VERSION);
update_option('health_tracker_installed', time());
}
public function deactivate() {
// 清理临时数据
// 注意:不删除用户数据
}
public function init() {
// 初始化短码
Health_Tracker_Shortcodes::init();
// 初始化API
Health_Tracker_API::init();
// 加载前端资源
add_action('wp_enqueue_scripts', array($this, 'enqueue_public_scripts'));
// 加载后台资源
add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'));
}
public function load_textdomain() {
load_plugin_textdomain('health-tracker', false, dirname(plugin_basename(__FILE__)) . '/languages/');
}
public function enqueue_public_scripts() {
// 前端资源加载
wp_enqueue_style('health-tracker-public', HEALTH_TRACKER_PLUGIN_URL . 'public/css/health-tracker-public.css', array(), HEALTH_TRACKER_VERSION);
wp_enqueue_script('health-tracker-public', HEALTH_TRACKER_PLUGIN_URL . 'public/js/health-tracker-public.js', array('jquery', 'chartjs'), HEALTH_TRACKER_VERSION, true);
// 本地化脚本
wp_localize_script('health-tracker-public', 'healthTrackerAjax', array(
'ajaxurl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('health_tracker_nonce'),
'user_id' => get_current_user_id()
));
}
public function enqueue_admin_scripts($hook) {
// 仅在我们的设置页面加载
if ('toplevel_page_health-tracker' !== $hook) {
return;
}
wp_enqueue_style('health-tracker-admin', HEALTH_TRACKER_PLUGIN_URL . 'admin/css/health-tracker-admin.css', array(), HEALTH_TRACKER_VERSION);
wp_enqueue_script('health-tracker-admin', HEALTH_TRACKER_PLUGIN_URL . 'admin/js/health-tracker-admin.js', array('jquery'), HEALTH_TRACKER_VERSION, true);
}
}
// 启动插件
Health_Tracker::get_instance();
3. 数据库设计与数据表创建
3.1 数据库表设计
我们需要创建两个主要数据表:
wp_health_data- 存储健康数据记录wp_health_metrics- 存储健康指标定义
3.2 数据库类实现
创建includes/class-database.php:
<?php
class Health_Tracker_Database {
public static function create_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$table_prefix = $wpdb->prefix . 'health_';
// 健康指标定义表
$metrics_table = $table_prefix . 'metrics';
$metrics_sql = "CREATE TABLE IF NOT EXISTS $metrics_table (
id mediumint(9) NOT NULL AUTO_INCREMENT,
metric_name varchar(100) NOT NULL,
metric_unit varchar(50) NOT NULL,
metric_type varchar(50) NOT NULL,
min_value decimal(10,2) DEFAULT NULL,
max_value decimal(10,2) DEFAULT NULL,
default_value decimal(10,2) DEFAULT NULL,
description text,
is_active tinyint(1) DEFAULT 1,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY metric_name (metric_name)
) $charset_collate;";
// 健康数据记录表
$data_table = $table_prefix . 'data';
$data_sql = "CREATE TABLE IF NOT EXISTS $data_table (
id bigint(20) NOT NULL AUTO_INCREMENT,
user_id bigint(20) NOT NULL,
metric_id mediumint(9) NOT NULL,
metric_value decimal(10,2) NOT NULL,
recorded_at datetime NOT NULL,
notes text,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY user_id (user_id),
KEY metric_id (metric_id),
KEY recorded_at (recorded_at),
FOREIGN KEY (metric_id) REFERENCES {$metrics_table}(id) ON DELETE CASCADE
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($metrics_sql);
dbDelta($data_sql);
// 插入默认健康指标
self::insert_default_metrics();
}
private static function insert_default_metrics() {
global $wpdb;
$table_name = $wpdb->prefix . 'health_metrics';
$default_metrics = array(
array(
'metric_name' => '体重',
'metric_unit' => 'kg',
'metric_type' => 'numeric',
'min_value' => 30,
'max_value' => 200,
'default_value' => 65,
'description' => '体重记录,单位千克'
),
array(
'metric_name' => '收缩压',
'metric_unit' => 'mmHg',
'metric_type' => 'numeric',
'min_value' => 80,
'max_value' => 200,
'default_value' => 120,
'description' => '血压高压值'
),
array(
'metric_name' => '舒张压',
'metric_unit' => 'mmHg',
'metric_type' => 'numeric',
'min_value' => 50,
'max_value' => 130,
'default_value' => 80,
'description' => '血压低压值'
),
array(
'metric_name' => '空腹血糖',
'metric_unit' => 'mmol/L',
'metric_type' => 'numeric',
'min_value' => 3.0,
'max_value' => 20.0,
'default_value' => 5.5,
'description' => '空腹血糖值'
),
array(
'metric_name' => '步数',
'metric_unit' => '步',
'metric_type' => 'numeric',
'min_value' => 0,
'max_value' => 50000,
'default_value' => 8000,
'description' => '每日步数'
),
array(
'metric_name' => '睡眠时长',
'metric_unit' => '小时',
'metric_type' => 'numeric',
'min_value' => 0,
'max_value' => 24,
'default_value' => 7.5,
'description' => '每日睡眠时长'
)
);
foreach ($default_metrics as $metric) {
$wpdb->replace($table_name, $metric);
}
}
public static function get_user_health_data($user_id, $metric_id = null, $start_date = null, $end_date = null, $limit = 100) {
global $wpdb;
$table_data = $wpdb->prefix . 'health_data';
$table_metrics = $wpdb->prefix . 'health_metrics';
$where_clauses = array("d.user_id = %d");
$where_values = array($user_id);
if ($metric_id) {
$where_clauses[] = "d.metric_id = %d";
$where_values[] = $metric_id;
}
if ($start_date) {
$where_clauses[] = "d.recorded_at >= %s";
$where_values[] = $start_date;
}
if ($end_date) {
$where_clauses[] = "d.recorded_at <= %s";
$where_values[] = $end_date;
}
$where_sql = implode(' AND ', $where_clauses);
$query = $wpdb->prepare(
"SELECT d.*, m.metric_name, m.metric_unit
FROM $table_data d
JOIN $table_metrics m ON d.metric_id = m.id
WHERE $where_sql
ORDER BY d.recorded_at DESC
LIMIT %d",
array_merge($where_values, array($limit))
);
return $wpdb->get_results($query);
}
public static function add_health_data($user_id, $metric_id, $value, $recorded_at = null, $notes = '') {
global $wpdb;
$table_name = $wpdb->prefix . 'health_data';
if (!$recorded_at) {
$recorded_at = current_time('mysql');
}
$data = array(
'user_id' => $user_id,
'metric_id' => $metric_id,
'metric_value' => $value,
'recorded_at' => $recorded_at,
'notes' => $notes
);
$format = array('%d', '%d', '%f', '%s', '%s');
return $wpdb->insert($table_name, $data, $format);
}
public static function get_available_metrics() {
global $wpdb;
$table_name = $wpdb->prefix . 'health_metrics';
return $wpdb->get_results(
"SELECT * FROM $table_name WHERE is_active = 1 ORDER BY metric_name"
);
}
}
4. 用户界面设计与前端开发
4.1 创建前端模板
在public/templates/目录下创建健康数据记录界面:
<!-- public/templates/dashboard.php -->
<div class="health-tracker-container">
<div class="health-tracker-header">
<h1><?php _e('个人健康数据记录', 'health-tracker'); ?></h1>
<p><?php _e('记录并分析您的健康指标', 'health-tracker'); ?></p>
</div>
<div class="health-tracker-main">
<!-- 数据录入部分 -->
<div class="health-tracker-section">
<h2><?php _e('新增记录', 'health-tracker'); ?></h2>
<form id="health-data-form" class="health-data-form">
<div class="form-group">
<label for="metric-select"><?php _e('选择指标', 'health-tracker'); ?></label>
<select id="metric-select" name="metric_id" required>
<option value=""><?php _e('请选择健康指标', 'health-tracker'); ?></option>
<!-- 通过AJAX动态加载 -->
</select>
</div>
<div class="form-group">
<label for="metric-value"><?php _e('数值', 'health-tracker'); ?></label>
<input type="number" id="metric-value" name="metric_value" step="0.01" required>
<span class="unit-display" id="unit-display"></span>
</div>
<div class="form-group">
<label for="record-date"><?php _e('记录日期', 'health-tracker'); ?></label>
<input type="datetime-local" id="record-date" name="recorded_at" value="<?php echo date('Y-m-dTH:i'); ?>">
</div>
<div class="form-group">
<label for="notes"><?php _e('备注', 'health-tracker'); ?></label>
<textarea id="notes" name="notes" rows="3" placeholder="<?php _e('可选的备注信息...', 'health-tracker'); ?>"></textarea>
</div>
<button type="submit" class="submit-btn">
<?php _e('保存记录', 'health-tracker'); ?>
</button>
</form>
</div>
<!-- 数据可视化部分 -->
<div class="health-tracker-section">
<h2><?php _e('趋势分析', 'health-tracker'); ?></h2>
<div class="chart-controls">
<select id="chart-metric-select">
<option value=""><?php _e('选择要分析的指标', 'health-tracker'); ?></option>
</select>
<select id="chart-period">
<option value="7"><?php _e('最近7天', 'health-tracker'); ?></option>
<option value="30" selected><?php _e('最近30天', 'health-tracker'); ?></option>
<button type="submit" class="submit-btn">
<?php _e('保存记录', 'health-tracker'); ?>
</button>
</form>
</div>
<!-- 数据可视化部分 -->
<div class="health-tracker-section">
<h2><?php _e('趋势分析', 'health-tracker'); ?></h2>
<div class="chart-controls">
<select id="chart-metric-select">
<option value=""><?php _e('选择要分析的指标', 'health-tracker'); ?></option>
</select>
<select id="chart-period">
<option value="7"><?php _e('最近7天', 'health-tracker'); ?></option>
<option value="30" selected><?php _e('最近30天', 'health-tracker'); ?></option>
<option value="90"><?php _e('最近90天', 'health-tracker'); ?></option>
<option value="365"><?php _e('最近1年', 'health-tracker'); ?></option>
</select>
<button id="update-chart" class="btn-secondary">
<?php _e('更新图表', 'health-tracker'); ?>
</button>
</div>
<div class="chart-container">
<canvas id="health-trend-chart"></canvas>
</div>
<div class="chart-stats" id="chart-stats">
<!-- 统计数据将通过JavaScript动态生成 -->
</div>
</div>
<!-- 历史记录部分 -->
<div class="health-tracker-section">
<h2><?php _e('历史记录', 'health-tracker'); ?></h2>
<div class="history-controls">
<select id="history-metric-filter">
<option value=""><?php _e('所有指标', 'health-tracker'); ?></option>
</select>
<input type="date" id="history-start-date" placeholder="<?php _e('开始日期', 'health-tracker'); ?>">
<input type="date" id="history-end-date" placeholder="<?php _e('结束日期', 'health-tracker'); ?>">
<button id="filter-history" class="btn-secondary">
<?php _e('筛选', 'health-tracker'); ?>
</button>
<button id="export-history" class="btn-secondary">
<?php _e('导出CSV', 'health-tracker'); ?>
</button>
</div>
<div class="history-table-container">
<table id="health-history-table" class="health-history-table">
<thead>
<tr>
<th><?php _e('指标', 'health-tracker'); ?></th>
<th><?php _e('数值', 'health-tracker'); ?></th>
<th><?php _e('记录时间', 'health-tracker'); ?></th>
<th><?php _e('备注', 'health-tracker'); ?></th>
<th><?php _e('操作', 'health-tracker'); ?></th>
</tr>
</thead>
<tbody>
<!-- 数据将通过JavaScript动态加载 -->
</tbody>
</table>
<div id="history-pagination" class="pagination">
<!-- 分页控件 -->
</div>
</div>
</div>
</div>
</div>
### 4.2 前端样式设计
创建`public/css/health-tracker-public.css`:
/ 健康追踪器主容器 /
.health-tracker-container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
}
.health-tracker-header {
text-align: center;
margin-bottom: 40px;
padding-bottom: 20px;
border-bottom: 2px solid #4CAF50;
}
.health-tracker-header h1 {
color: #2c3e50;
margin-bottom: 10px;
}
.health-tracker-header p {
color: #7f8c8d;
font-size: 1.1em;
}
/ 各部分样式 /
.health-tracker-section {
background: white;
border-radius: 10px;
padding: 25px;
margin-bottom: 30px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
border: 1px solid #e0e0e0;
}
.health-tracker-section h2 {
color: #3498db;
margin-top: 0;
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 1px solid #eee;
}
/ 表单样式 /
.health-data-form .form-group {
margin-bottom: 20px;
}
.health-data-form label {
display: block;
margin-bottom: 8px;
font-weight: 600;
color: #34495e;
}
.health-data-form select,
.health-data-form input[type="number"],
.health-data-form input[type="datetime-local"],
.health-data-form textarea {
width: 100%;
padding: 12px;
border: 1px solid #ddd;
border-radius: 6px;
font-size: 16px;
transition: border-color 0.3s;
box-sizing: border-box;
}
.health-data-form select:focus,
.health-data-form input:focus,
.health-data-form textarea:focus {
outline: none;
border-color: #3498db;
box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.2);
}
.unit-display {
margin-left: 10px;
color: #7f8c8d;
font-style: italic;
}
.submit-btn {
background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%);
color: white;
border: none;
padding: 14px 28px;
font-size: 16px;
border-radius: 6px;
cursor: pointer;
transition: all 0.3s;
font-weight: 600;
width: 100%;
}
.submit-btn:hover {
background: linear-gradient(135deg, #45a049 0%, #3d8b40 100%);
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
/ 图表控制区域 /
.chart-controls,
.history-controls {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-bottom: 20px;
align-items: center;
}
.chart-controls select,
.history-controls select,
.history-controls input {
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
}
.btn-secondary {
background: #3498db;
color: white;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
transition: background 0.3s;
}
.btn-secondary:hover {
background: #2980b9;
}
/ 图表容器 /
.chart-container {
position: relative;
height: 400px;
margin: 20px 0;
background: #f8f9fa;
border-radius: 8px;
padding: 15px;
}
.chart-stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 15px;
margin-top: 20px;
}
.stat-card {
background: white;
padding: 15px;
border-radius: 6px;
border-left: 4px solid #3498db;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.stat-card h4 {
margin: 0 0 10px 0;
color: #7f8c8d;
font-size: 14px;
text-transform: uppercase;
}
.stat-card .stat-value {
font-size: 24px;
font-weight: bold;
color: #2c3e50;
}
.stat-card .stat-change {
font-size: 14px;
margin-top: 5px;
}
.stat-change.positive {
color: #27ae60;
}
.stat-change.negative {
color: #e74c3c;
}
/ 历史记录表格 /
.history-table-container {
overflow-x: auto;
}
.health-history-table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
.health-history-table th {
background: #f8f9fa;
padding: 12px;
text-align: left;
font-weight: 600;
color: #2c3e50;
border-bottom: 2px solid #dee2e6;
}
.health-history-table td {
padding: 12px;
border-bottom: 1px solid #dee2e6;
}
.health-history-table tr:hover {
background: #f8f9fa;
}
.health-history-table .metric-name {
font-weight: 600;
color: #3498db;
}
.health-history-table .metric-value {
font-weight: bold;
color: #2c3e50;
}
.health-history-table .metric-unit {
color: #7f8c8d;
font-size: 0.9em;
margin-left: 2px;
}
.health-history-table .record-time {
color: #7f8c8d;
font-size: 0.9em;
}
.health-history-table .action-buttons {
display: flex;
gap: 5px;
}
.action-btn {
padding: 5px 10px;
border: none;
border-radius: 3px;
cursor: pointer;
font-size: 12px;
transition: all 0.2s;
}
.edit-btn {
background: #f39c12;
color: white;
}
.delete-btn {
background: #e74c3c;
color: white;
}
.action-btn:hover {
opacity: 0.9;
transform: translateY(-1px);
}
/ 分页样式 /
.pagination {
display: flex;
justify-content: center;
align-items: center;
margin-top: 20px;
gap: 10px;
}
.pagination button {
padding: 8px 16px;
border: 1px solid #ddd;
background: white;
cursor: pointer;
border-radius: 4px;
transition: all 0.3s;
}
.pagination button:hover:not(:disabled) {
background: #3498db;
color: white;
border-color: #3498db;
}
.pagination button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.pagination .page-info {
color: #7f8c8d;
font-size: 14px;
}
/ 响应式设计 /
@media (max-width: 768px) {
.health-tracker-container {
padding: 10px;
}
.health-tracker-section {
padding: 15px;
}
.chart-controls,
.history-controls {
flex-direction: column;
align-items: stretch;
}
.chart-container {
height: 300px;
}
.health-history-table {
font-size: 14px;
}
.health-history-table th,
.health-history-table td {
padding: 8px;
}
}
/ 加载动画 /
.loading {
display: inline-block;
width: 20px;
height: 20px;
border: 3px solid #f3f3f3;
border-top: 3px solid #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/ 消息提示 /
.message {
padding: 12px;
border-radius: 6px;
margin: 10px 0;
display: none;
}
.message.success {
background: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.message.error {
background: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
.message.info {
background: #d1ecf1;
color: #0c5460;
border: 1px solid #bee5eb;
}
### 4.3 前端JavaScript逻辑
创建`public/js/health-tracker-public.js`:
(function($) {
'use strict';
// 全局变量
let healthTracker = {
metrics: [],
currentChart: null,
currentPage: 1,
itemsPerPage: 10,
currentFilter: {}
};
// 初始化
$(document).ready(function() {
initHealthTracker();
});
function initHealthTracker() {
// 加载健康指标
loadMetrics();
// 绑定事件
bindEvents();
// 加载历史记录
loadHistory();
}
function loadMetrics() {
$.ajax({
url: healthTrackerAjax.ajaxurl,
type: 'POST',
data: {
action: 'health_tracker_get_metrics',
nonce: healthTrackerAjax.nonce
},
beforeSend: function() {
$('#metric-select, #chart-metric-select, #history-metric-filter').append(
'<option value="" disabled>加载中...</option>'
);
},
success: function(response) {
if (response.success) {
healthTracker.metrics = response.data;
populateMetricSelects();
} else {
showMessage('error', '加载指标失败: ' + response.data);
}
},
error: function() {
showMessage('error', '网络错误,请稍后重试');
}
});
}
function populateMetricSelects() {
// 清空所有选择框
$('#metric-select, #chart-metric-select, #history-metric-filter').empty();
// 添加默认选项
$('#metric-select').append('<option value="">请选择健康指标</option>');
$('#chart-metric-select').append('<option value="">选择要分析的指标</option>');
$('#history-metric-filter').append('<option value="">所有指标</option>');
// 添加指标选项
healthTracker.metrics.forEach(function(metric) {
$('#metric-select').append(
`<option value="${metric.id}" data-unit="${metric.metric_unit}">${metric.metric_name} (${metric.metric_unit})</option>`
);
$('#chart-metric-select').append(
`<option value="${metric.id}">${metric.metric_name}</option>`
);
$('#history-metric-filter').append(
`<option value="${metric.id}">${metric.metric_name}</option>`
);
});
}
function bindEvents() {
// 指标选择变化时更新单位显示
$('#metric-select').on('change', function() {
const selectedOption = $(this).find('option:selected');
const unit = selectedOption.data('unit');
$('#unit-display').text(unit ? `单位: ${unit}` : '');
});
// 提交健康数据表单
$('#health-data-form').on('submit', function(e) {
e.preventDefault();
submitHealthData();
});
// 更新图表
$('#update-chart').on('click', function() {
updateChart();
});
// 筛选历史记录
$('#filter-history').on('click', function() {
healthTracker.currentPage = 1;
updateHistoryFilter();
loadHistory();
});
// 导出历史记录
$('#export-history').on('click', function() {
exportHistoryToCSV();
});
// 图表指标选择变化时自动更新图表
$('#chart-metric-select').on('change', function() {
if ($(this).val()) {
updateChart();
}
});
// 分页按钮
$(document).on('click', '.page-btn', function() {
const page = $(this).data('page');
if (page) {
healthTracker.currentPage = page;
loadHistory();
}
});
}
function submitHealthData() {
const formData = $('#health-data-form').serializeArray();
const data = {};
// 转换为对象
formData.forEach(function(item) {
data[item.name] = item.value;
});
// 添加用户ID
data.user_id = healthTrackerAjax.user_id;
data.action = 'health_tracker_add_data';
data.nonce = healthTrackerAjax.nonce;
$.ajax({
url: healthTrackerAjax.ajaxurl,
type: 'POST',
data: data,
beforeSend: function() {
$('.submit-btn').prop('disabled', true).html('<span class="loading"></span> 保存中...');
},
success: function(response) {
if (response.success) {
showMessage('success', '数据保存成功!');
$('#health-data-form')[0].reset();
$('#unit-display').text('');
// 重新加载历史记录
loadHistory();
// 如果当前图表显示的是刚添加的指标,更新图表
const selectedMetric = $('#chart-metric-select').val();
if (selectedMetric && selectedMetric == data.metric_id) {
updateChart();
}
} else {
showMessage('error', '保存失败: ' + response.data);
}
},
error: function() {
showMessage('error', '网络错误,请稍后重试');
},
complete: function() {
$('.submit-btn').prop('disabled', false).text('保存记录');
}
});
}
function updateChart() {
const metric
