No description
  • Go 54.9%
  • HTML 39.6%
  • CSS 3.1%
  • JavaScript 2.4%
Find a file
2026-05-24 00:01:20 +08:00
.idea Init Commit 2026-05-23 23:27:20 +08:00
database 修改Card大小并将代码模板写进数据库 2026-05-24 00:01:20 +08:00
email Init Commit 2026-05-23 23:27:20 +08:00
handlers 修改Card大小并将代码模板写进数据库 2026-05-24 00:01:20 +08:00
middleware Init Commit 2026-05-23 23:27:20 +08:00
models 修改Card大小并将代码模板写进数据库 2026-05-24 00:01:20 +08:00
static 修改Card大小并将代码模板写进数据库 2026-05-24 00:01:20 +08:00
.env.exp Init Commit 2026-05-23 23:28:04 +08:00
.gitignore Init Commit 2026-05-23 23:27:20 +08:00
go.mod Init Commit 2026-05-23 23:27:20 +08:00
go.sum Init Commit 2026-05-23 23:27:20 +08:00
main.go 修改Card大小并将代码模板写进数据库 2026-05-24 00:01:20 +08:00
README.md Init Commit 2026-05-23 23:27:20 +08:00

HealthCheck

每日健康打卡系统 —— 记录健康状态,关注身体变化。

功能特性

  • 多数据库支持: SQLite / MySQL / PostgreSQL / MSSQL
  • 用户认证: 注册、邮箱验证、登录、忘记/重置密码
  • JWT 认证: HS256 令牌,可配置过期时间
  • API 令牌: 创建/查看/删除设备令牌,支持程序化访问
  • 健康记录: 提交和查询心率、血氧、卡路里、步数、睡眠时长,自动刷新,折线图可视化
  • 头像: Gravatar 集成(可配置镜像)+ 自定义上传JPG/PNG/GIF, 最大 2MB
  • 邮件: SMTPSSL 465 / STARTTLS 587可配置发件人调试日志
  • 邮件模板: 存储在数据库中,管理员可在线编辑,支持 {{.Code}}{{.Link}} 占位符
  • 管理员系统: 首个注册用户自动成为管理员;独立管理面板
  • 展示卡片: 创建公开心率卡片,支持 3 种样式 + 折线图 + WebSocket 实时推送
  • 超级管理员: ID=1 的用户为超级管理员,不可修改/删除
  • 设备名追踪: 通过 API 令牌上传心率时自动记录设备名称

Quick Start

Prerequisites

  • Go 1.22+
  • SMTP server (optional, for email verification)

Setup

# Clone and enter directory
cd HealthCheck

# Copy .env and edit
cp .env.example .env

# Install dependencies
go mod tidy

# Build
go build -o healthcheck .

# Run
./healthcheck

Server starts at http://localhost:8080.

Environment Variables (.env)

Variable Default Description
DB_TYPE sqlite Database type: sqlite, mysql, postgres, mssql
DB_DSN "" Custom DSN (leave empty for default)
SMTP_HOST - SMTP server hostname
SMTP_PORT - SMTP port (465 for SSL, 587 for STARTTLS)
SMTP_USER - SMTP authentication username
SMTP_PASS - SMTP authentication password
SMTP_FROM - From address in outgoing emails (e.g. name <email>)
JWT_SECRET - Secret key for JWT signing
JWT_EXPIRY 24h JWT token expiry duration
SERVER_PORT 8080 HTTP server port
ADMIN_PAGE /manage Admin panel route path
GRAVATAR_MIRROR https://www.gravatar.com/avatar/ Gravatar mirror URL
DEBUG false Enable SMTP debug logging

Frontend

Pages

Route Description
/ Landing page
/login.html Login
/register.html Register
/verify.html Email verification
/forgot-password.html Forgot password
/reset-password.html Reset password
/dashboard.html Main console (profile, cards, tokens, health records)
/manage (or ADMIN_PAGE) Admin panel (users, devices, records, templates)
/card/{token} Public card view (heart rate badge with chart)

Dashboard Features

  • 个人信息: 展示/编辑头像、昵称、邮箱等
  • 健康概览: 汇总展示最新心率、血氧、卡路里、步数、睡眠数据及来源设备
  • 展示卡片: 创建公开心率卡片,支持 3 种样式和 3 种数据颗粒度,展示全部健康指标
  • API 令牌: 管理设备访问令牌
  • 心率记录: 实时列表(含所有指标)+ 折线图,每 5 秒自动刷新
  • 管理面板入口: admin 用户可见「进入管理面板」按钮

Card Styles

Style 名称 描述
style1 深色渐变 深色背景 + 紫色渐变文字 + 折线图
style2 简约边框 白色背景 + 紫色边框
style3 渐变彩色 紫色渐变背景 + 白色文字

Card Granularity (数据颗粒度)

Granularity 描述 WebSocket
realtime 实时最新心率 每 3 秒推送
hourly 每小时平均 静态显示
daily 每日平均 静态显示

Card URL format: /card/{token} — 显示 BPM、折线图、设备名、时间。

API Reference

All responses follow the format:

{
  "success": true/false,
  "message": "...",
  "data": { ... }
}

Auth

Register

POST /api/register
Content-Type: application/json

{
  "nickname": "My Server",
  "email": "user@example.com",
  "password": "password123"
}

Response 200:

{
  "success": true,
  "message": "Registered. Check your email for verification code."
}

Note: If email sending fails, the verification code is included in the message.

First registered user gets role: admin and becomes super admin (ID=1).

Verify Email

POST /api/verify-email
Content-Type: application/json

{
  "email": "user@example.com",
  "code": "123456"
}

Login

POST /api/login
Content-Type: application/json

{
  "email": "user@example.com",
  "password": "password123"
}

Response 200:

{
  "success": true,
  "data": {
    "token": "eyJhbGci...",
    "expires_at": "2026-05-24T...",
    "user_id": 1,
    "nickname": "My Server",
    "role": "admin"
  }
}

Forgot Password

POST /api/forgot-password
Content-Type: application/json

{
  "email": "user@example.com"
}

Sends a password reset link to the email.

Reset Password

POST /api/reset-password
Content-Type: application/json

{
  "token": "reset-token-from-email",
  "password": "newpassword123"
}

Profile

Requires Authorization: Bearer <jwt_token> header.

Get Profile

GET /api/profile

Response:

{
  "success": true,
  "data": {
    "id": 1,
    "nickname": "My Server",
    "email": "user@example.com",
    "email_verified": true,
    "role": "admin",
    "avatar_url": "https://www.gravatar.com/avatar/...",
    "created_at": "2026-05-23T..."
  }
}

健康记录

Requires JWT or API Token auth. API token uploads automatically record device name.

提交记录

POST /api/records
Content-Type: application/json

{
  "bpm": 99,
  "calories": 350.5,
  "steps": 8521,
  "sleep": 7.5,
  "spo2": 98
}

All fields except bpm are optional. Devices can submit partial data.

查询记录

GET /api/records

Returns last 50 records with all metrics. Supports ?c=5 for custom count.

Response record format:

{
  "id": 1,
  "user_id": 1,
  "bpm": 99,
  "calories": 350.5,
  "steps": 8521,
  "sleep": 7.5,
  "spo2": 98,
  "device_name": "My Band",
  "recorded_at": "...",
  "created_at": "..."
}

Tokens (Device API Tokens)

Requires JWT auth.

List Tokens

GET /api/tokens

Create Token

POST /api/tokens
Content-Type: application/json

{
  "name": "my-device",
  "token": "optional-custom-token-string"
}

Delete Token

DELETE /api/tokens
Content-Type: application/json

{
  "id": 1
}

Cards

Requires JWT auth.

List Cards

GET /api/cards

Create Card

POST /api/cards
Content-Type: application/json

{
  "title": "My Health",
  "style": "style1",
  "granularity": "realtime"
}

Delete Card

DELETE /api/cards/{id}

View Card (Public)

GET /card/{token}

Returns an HTML page with BPM display, line chart, device name, and optional WebSocket for realtime updates.

Card WebSocket

GET /ws/card/{token}

WebSocket endpoint (only for realtime granularity cards). Pushes JSON every 3 seconds:

{
  "bpm": 88,
  "time": "14:30:00",
  "device": "My Phone",
  "spo2": 98,
  "calories": 350.5,
  "steps": 8521,
  "sleep": 7.5
}

Avatar

Upload Avatar

Requires JWT auth.

POST /api/avatar/upload
Authorization: Bearer <jwt_token>
Content-Type: multipart/form-data

avatar: <file>

Supported formats: JPG, PNG, GIF. Max size: 2MB.

Serve Avatar

GET /api/avatar/{filename}

Avatar URL Resolution

  • If user has uploaded a custom avatar: /api/avatar/{filename}
  • Otherwise: Gravatar URL via configured GRAVATAR_MIRROR

Admin

Requires JWT auth with role: admin. ID=1 is super admin and cannot be modified/deleted.

User Management

GET    /api/admin/users          # List all users
PUT    /api/admin/users/{id}     # Update user role {"role":"admin|user"}
DELETE /api/admin/users/{id}     # Delete user

Device Management

GET    /api/admin/devices        # List all devices
DELETE /api/admin/devices/{id}   # Delete device

Record Management

GET    /api/admin/records        # List all records (?c=50&o=0)
DELETE /api/admin/records/{id}   # Delete record

Template Management

GET  /api/admin/templates            # List templates
GET  /api/admin/templates/{name}     # Get template
PUT  /api/admin/templates/{name}     # Update template

Request body for template update:

{
  "subject": "Email Subject with {{.Code}}",
  "body": "<h1>Your code: {{.Code}}</h1>"
}

Available template variables:

  • {{.Code}} — verification code (for verify_email)
  • {{.Link}} — reset link (for reset_password)

Default template names: verify_email, reset_password

Auth Methods

JWT Token: Include in header: Authorization: Bearer <jwt_token>

API Token: Include in header: Authorization: Bearer <api_token>

API tokens bypass email verification requirement.

Database

Default database is SQLite, stored at ./data/healthcheck.db.

Tables

Table Description
users User accounts with roles
heart_rates Health records with device name tracking
devices API device tokens
templates Email templates (admin editable)
cards Public shareable heart rate cards

Supported databases:

DB_TYPE Driver Default DSN
sqlite modernc.org/sqlite ./data/healthcheck.db
mysql go-sql-driver/mysql user:password@tcp(localhost:3306)/healthcheck
postgres lib/pq host=127.0.0.1 dbname=healthcheck user=postgres password=password sslmode=disable
mssql go-mssqldb server=127.0.0.1;database=healthcheck;user id=sa;password=password;

Project Structure

├── main.go              # Entry point, route registration
├── .env                 # Configuration
├── database/
│   ├── database.go      # Multi-dialect init, DDL, migrations
│   ├── users.go         # User CRUD
│   ├── heart.go         # Health record CRUD
│   ├── devices.go       # Device token CRUD
│   ├── templates.go     # Email template CRUD
│   ├── cards.go         # Card CRUD
│   └── admin.go         # Admin user/device/record queries
├── models/
│   └── models.go        # Data structures, request/response types
├── handlers/
│   ├── auth.go          # Register, verify, login, forgot/reset, profile
│   ├── heartbeat.go     # Health record submit + query
│   ├── avatar.go        # Gravatar + upload + serve
│   ├── token.go         # Device token management
│   ├── admin.go         # Template management
│   ├── admin_users.go   # Admin users/devices/records CRUD
│   ├── card.go          # Card CRUD + public card view
│   └── ws.go            # WebSocket hub + card broadcast
├── middleware/
│   └── jwt.go           # JWT generate/parse, Auth/Admin middleware, CORS
├── email/
│   └── email.go         # SMTP (SSL + STARTTLS), template rendering
└── static/
    ├── index.html        # Landing page
    ├── login.html        # Login
    ├── register.html     # Register
    ├── verify.html       # Email verification
    ├── forgot-password.html
    ├── reset-password.html
    ├── dashboard.html    # Main console (profile, cards, tokens, records)
    ├── admin.html        # Admin panel (users, devices, records, templates)
    ├── css/style.css
    └── js/api.js