132-基于Python的中老年体检数据可视化分析系统

中老年体检数据可视化分析系统 --- 技术文档

目录

  1. 项目概述
  2. 系统架构
  3. 技术栈
  4. 目录结构
  5. 数据库设计
  6. 核心模块详解
  7. 路由与接口设计
  8. 前端页面设计
  9. 数据可视化方案
  10. 安全机制
  11. 部署与运行
  12. 数据字典
  13. 已知问题与改进建议

1. 项目概述

1.1 项目背景

本系统是一个面向中老年群体体检数据的可视化分析平台,基于 Python + Flask + MySQL 构建。系统整合了来自和鲸社区(Heywhale)的公开数据集,包含 4,909 条中老年居民体检记录,涵盖高血压、心脏病、中风等慢性病指标以及血糖、BMI 等基础健康数据。

1.2 核心功能

功能模块 说明
数据总览 关键指标卡片、仪表盘、疾病分布、年龄/性别/地域多维分析
规律分析 相关性热力图、平行坐标、树图、疾病共现、风险分层等深度分析
趋势分析 性别对比、年龄趋势、城乡差异、工作类型/婚姻/吸烟影响分析
数据管理 管理员 CRUD、CSV 批量导入、分页浏览
重点关注 个人关注列表、风险评估、健康建议、Markdown 报告导出
用户系统 注册登录、角色权限、个人资料管理

1.3 目标用户

  • 医疗健康研究人员
  • 公共卫生管理者
  • 数据分析学习者
  • 中老年健康管理机构

























2. 系统架构

2.1 整体架构

系统采用经典的四层分层架构:

复制代码
┌─────────────────────────────────────────────────────────┐
│                    浏览器 (Browser)                       │
│         HTML + CSS + Bootstrap + Plotly.js               │
└──────────────────────────┬──────────────────────────────┘
                           │ HTTP
┌──────────────────────────▼──────────────────────────────┐
│                 Web 层 (app.py --- Flask)                   │
│     路由处理 · Session 认证 · 请求过滤 · 模板渲染            │
├─────────────────────────────────────────────────────────┤
│               业务逻辑层 (analytics.py)                    │
│     风险评分 · 数据富化 · 统计分析 · 洞察生成                 │
├─────────────────────────────────────────────────────────┤
│               数据访问层 (database.py)                     │
│     MySQL CRUD · 密码哈希 · CSV 导入 · SQLAlchemy          │
├─────────────────────────────────────────────────────────┤
│               配置层 (config.py)                          │
│     数据库连接 · 字段定义 · 选项常量                         │
├─────────────────────────────────────────────────────────┤
│               数据存储                                     │
│     MySQL (design_132_health)  ·  CSV 文件                │
└─────────────────────────────────────────────────────────┘

2.2 数据流

复制代码
CSV 文件 ──→ import_data.py ──→ MySQL (health_records)
                                      │
                                      ▼
                              database.py (load_health_records)
                                      │
                                      ▼
                              pandas DataFrame
                                      │
                          ┌───────────┼───────────┐
                          ▼           ▼           ▼
                    apply_filters  enrich_records  statistics
                          │           │           │
                          └───────────┼───────────┘
                                      ▼
                              JSON 数据 (tojson)
                                      │
                                      ▼
                            Jinja2 模板渲染 HTML
                                      │
                                      ▼
                          Plotly.js 客户端图表渲染

2.3 请求处理流程

  1. 用户发起 HTTP 请求
  2. Flask 路由匹配,装饰器检查 Session 认证
  3. 从 MySQL 加载全量数据到 pandas DataFrame
  4. 根据 URL 查询参数应用过滤条件
  5. 对过滤后数据进行富化(风险评分、分层标注)
  6. 计算统计指标、生成图表数据
  7. 通过 Jinja2 模板引擎渲染 HTML,数据以 JSON 形式嵌入
  8. 浏览器加载 Plotly.js 渲染交互式图表

3. 技术栈

3.1 后端

技术 版本要求 用途
Python >= 3.8 运行环境
Flask 内置(无版本约束) Web 框架
pandas >= 2.0 数据处理与分析
PyMySQL >= 1.1 MySQL 数据库驱动
SQLAlchemy >= 2.0 数据库引擎(pandas SQL 操作)

3.2 前端

技术 版本 用途
Bootstrap 暗色主题 UI 组件库与响应式布局
Plotly.js 2.35.2 客户端交互式图表
Jinja2 Flask 内置 模板引擎
自定义 CSS --- 774 行暗色主题样式

3.3 数据库

技术 说明
MySQL 主数据库,库名 design_132_health
字符集 utf8mb4(支持完整 Unicode)

4. 目录结构

复制代码
health/
├── app.py                    # Flask 主应用(1,117 行)
├── analytics.py              # 数据分析引擎(251 行)
├── database.py               # 数据库访问层(449 行)
├── config.py                 # 全局配置(80 行)
├── import_data.py            # CLI 数据导入工具(39 行)
├── requirements.txt          # Python 依赖清单
├── README.md                 # 项目说明
│
├── data/
│   ├── lf44k151_lnrjk.csv                    # 主数据集(4,909 条)
│   ├── 居民体检糖尿病及心血管健康指标数据集_readme.md  # 数据集说明
│   └── 参考链接.url                           # 数据来源链接
│
├── static/
│   ├── css/
│   │   └── bootstrap.min.css                  # Bootstrap 暗色主题
│   ├── js/
│   │   ├── bootstrap.bundle.min.js            # Bootstrap JS
│   │   └── plotly-2.35.2.min.js               # Plotly.js 图表库
│   └── style.css                              # 自定义样式(774 行)
│
└── templates/
    ├── base.html              # 基础布局(侧边栏 + 内容区)
    ├── login.html             # 登录/注册页
    ├── dashboard.html         # 数据总览页
    ├── analysis.html          # 规律分析页
    ├── trend.html             # 趋势分析页
    ├── manage.html            # 数据管理页(管理员)
    ├── focus.html             # 重点关注页
    └── profile.html           # 个人中心页

5. 数据库设计

5.1 ER 关系图

复制代码
┌──────────────┐       ┌───────────────────┐       ┌──────────────────┐
│    users     │       │  tracked_people   │       │  health_records  │
├──────────────┤       ├───────────────────┤       ├──────────────────┤
│ id (PK)      │──┐    │ id (PK)           │    ┌──│ id (PK)          │
│ username      │  │    │ user_id (FK)      │────┘  │ addtime          │
│ password_hash │  └───│ record_id (FK)    │───────│ xingbie          │
│ display_name  │      │ attention_level   │       │ nianling         │
│ email         │      │ note              │       │ gxy, xzb, sfzf   │
│ phone         │      │ created_at        │       │ xtsp, bmi        │
│ role          │      │ updated_at        │       │ ... (其他字段)    │
│ created_at    │      └───────────────────┘       └──────────────────┘
│ updated_at    │
└──────────────┘

5.2 表结构定义

5.2.1 users 表(用户表)
字段 类型 约束 说明
id BIGINT PK, AUTO_INCREMENT 用户 ID
username VARCHAR(64) NOT NULL, UNIQUE 用户名
password_hash VARCHAR(255) NOT NULL 密码哈希值
display_name VARCHAR(80) NULL 显示名称
email VARCHAR(120) NULL 邮箱
phone VARCHAR(40) NULL 手机号
role VARCHAR(20) DEFAULT 'user' 角色:user / admin
created_at DATETIME DEFAULT CURRENT_TIMESTAMP 创建时间
updated_at DATETIME ON UPDATE CURRENT_TIMESTAMP 更新时间
5.2.2 health_records 表(体检记录表)
字段 类型 约束 说明
id BIGINT PK, AUTO_INCREMENT 记录 ID
addtime DATETIME NULL 录入时间
xingbie VARCHAR(20) NULL 性别(男性/女性)
nianling INT NULL 年龄
gxy TINYINT NULL 高血压(0/1)
xzb TINYINT NULL 心脏病(0/1)
hunyin TINYINT NULL 婚姻状态(0=未婚/1=已婚)
gzxz VARCHAR(80) NULL 工作性质
zzxz VARCHAR(40) NULL 城乡属性(城市/农村)
xtsp DOUBLE NULL 血糖指标(mg/dL)
bmi DOUBLE NULL BMI 指数
xyzk VARCHAR(40) NULL 吸烟状态
sfzf TINYINT NULL 是否中风(0/1)
yearin INT NULL 调查年份
monthin INT NULL 调查月份
dayin INT NULL 调查日
v_bthyr INT NULL 出生年
v_bthmon INT NULL 出生月
type INT NULL 样本类型
prov INT NULL 省份编码
residenc INT NULL 居住编码(1=中心城区/2=县城乡镇/3=村庄)
trueage INT NULL 真实年龄

索引:

索引名 字段 类型
idx_age nianling 普通索引
idx_gender xingbie 普通索引
idx_area zzxz 普通索引
idx_disease gxy, xzb, sfzf 复合索引
5.2.3 tracked_people 表(关注人员表)
字段 类型 约束 说明
id BIGINT PK, AUTO_INCREMENT 记录 ID
user_id BIGINT FK → users.id, CASCADE 用户 ID
record_id BIGINT FK → health_records.id, CASCADE 体检记录 ID
attention_level VARCHAR(20) DEFAULT '重点关注' 关注级别
note TEXT NULL 备注
created_at DATETIME DEFAULT CURRENT_TIMESTAMP 创建时间
updated_at DATETIME ON UPDATE CURRENT_TIMESTAMP 更新时间

唯一约束: (user_id, record_id) --- 同一用户对同一记录只能关注一次

5.3 自动初始化机制

系统首次启动时自动执行以下流程(bootstrap_database()):

  1. 检测 MySQL 连接,若数据库不存在则自动创建
  2. 执行 CREATE TABLE IF NOT EXISTS 创建三张表
  3. users 表为空,插入默认管理员(admin / 123456)
  4. health_records 表为空且 CSV 文件存在,自动导入全部数据

6. 核心模块详解

6.1 config.py --- 配置模块

职责: 集中管理所有静态配置项。

关键配置项:

python 复制代码
# 数据库连接(支持环境变量覆盖)
DB_CONFIG = {
    "host": os.getenv("HEALTH_DB_HOST", "localhost"),
    "port": int(os.getenv("HEALTH_DB_PORT", "3306")),
    "user": os.getenv("HEALTH_DB_USER", "root"),
    "password": os.getenv("HEALTH_DB_PASSWORD", "123456"),
    "database": os.getenv("HEALTH_DB_NAME", "design_132_health"),
    "charset": "utf8mb4",
}

# 22 个标准字段名
HEALTH_COLUMNS = ["id", "addtime", "xingbie", "nianling", "gxy", "xzb",
                  "hunyin", "gzxz", "zzxz", "xtsp", "bmi", "xyzk", "sfzf",
                  "yearin", "monthin", "dayin", "v_bthyr", "v_bthmon", "type",
                  "prov", "residenc", "trueage"]

# 中文标签映射
COLUMN_LABELS = {"id": "编号", "addtime": "录入时间", "xingbie": "性别", ...}

# 下拉选项
GENDER_OPTIONS = ["男性", "女性"]
WORK_OPTIONS = ["私人企业", "自雇人士", "政府部门", "儿童"]
AREA_OPTIONS = ["城市", "农村"]
SMOKE_OPTIONS = ["从不吸烟", "以前吸烟", "吸烟", "不详"]
ATTENTION_LEVELS = ["一般关注", "重点关注", "高危随访"]

环境变量支持:

环境变量 对应配置 默认值
HEALTH_DB_HOST 数据库主机 localhost
HEALTH_DB_PORT 数据库端口 3306
HEALTH_DB_USER 数据库用户 root
HEALTH_DB_PASSWORD 数据库密码 123456
HEALTH_DB_NAME 数据库名称 design_132_health

6.2 database.py --- 数据访问层

职责: 封装所有 MySQL 交互操作,提供统一的数据访问接口。

密码安全:

python 复制代码
PASSWORD_ITERATIONS = 180_000  # PBKDF2 迭代次数

def hash_password(password, salt=None, iterations=180_000):
    # 格式: pbkdf2_sha256$iterations$salt$digest
    salt = salt or secrets.token_hex(16)
    digest = hashlib.pbkdf2_hmac("sha256", password.encode(), salt.encode(), iterations).hex()
    return f"pbkdf2_sha256${iterations}${salt}${digest}"

def verify_password(password, encoded):
    # 使用 hmac.compare_digest 防止时序攻击
    ...

核心函数列表:

函数 参数 返回值 说明
init_schema() None 初始化数据库、表结构、默认管理员
ensure_database() None 确保数据库存在
seed_default_admin() None 插入默认管理员
create_user() username, password, display_name, email, phone (bool, str) 注册新用户
authenticate_user() username, password dict or None 验证用户凭据
hash_password() password, salt, iterations str 生成密码哈希
verify_password() password, encoded bool 验证密码
update_user_profile() user_id, display_name, email, phone None 更新用户资料
change_password() user_id, old_password, new_password (bool, str) 修改密码
load_health_records() DataFrame 加载全部体检记录
get_record() record_id dict or None 获取单条记录
health_record_count() int 统计记录总数
insert_health_record() data: dict int 插入单条记录,返回 ID
upsert_health_dataframe() df: DataFrame int 批量插入/更新记录
delete_health_records() record_ids: list int 批量删除记录
import_csv_to_mysql() csv_path, replace int 导入 CSV 到 MySQL
add_favorite() user_id, record_id, level, note None 添加关注
update_favorite() user_id, record_id, level, note None 更新关注
remove_favorites() user_id, record_ids int 移除关注
load_favorites() user_id DataFrame 加载用户关注列表

数据类型处理:

python 复制代码
INTEGER_COLUMNS = {"id", "nianling", "gxy", "xzb", "hunyin", "sfzf",
                   "yearin", "monthin", "dayin", "v_bthyr", "v_bthmon",
                   "type", "prov", "residenc", "trueage"}
FLOAT_COLUMNS = {"xtsp", "bmi"}

所有数据写入前经过 _safe_value() 函数进行类型转换和空值处理。

连接管理:

  • 使用 PyMySQL 直连(_connect())执行 DDL 和简单 CRUD
  • 使用 SQLAlchemy Engine(get_engine())配合 pandas 执行复杂查询
  • 启用 pool_pre_ping=Truepool_recycle=3600 防止连接超时

6.3 analytics.py --- 数据分析引擎

职责: 负责数据富化、风险评分、统计分析和洞察生成。

6.3.1 风险评分算法(compute_risk_score)

综合多维健康指标,计算 0-100 分的风险评分:

因素 条件 分值 最大贡献
年龄 >= 80 岁 24 分 24
年龄 70-79 岁 18 分
年龄 60-69 岁 13 分
年龄 45-59 岁 7 分
高血压 gxy = 1 18 分 18
心脏病 xzb = 1 16 分 16
中风 sfzf = 1 20 分 20
BMI >= 28(肥胖) 12 分 12
BMI 24-27.99(超重) 6 分
血糖 >= 126(糖尿病风险) 16 分 16
血糖 100-125.99(偏高) 8 分
吸烟 "吸烟" 8 分 8
吸烟 "以前吸烟" 4 分

风险等级划分:

等级 分数区间 标签
低风险 0 - 29.9 低风险
中风险 30 - 59.9 中风险
高风险 60 - 79.9 高风险
重点随访 80 - 100 重点随访
6.3.2 数据富化(enrich_records)

在原始数据基础上添加计算列:

新增列 计算方式 分层规则
年龄段 pd.cut(nianling) <=44 / 45-59 / 60-69 / 70-79 / >=80
BMI分层 pd.cut(bmi) <18.5 偏瘦 / 18.5-24 正常 / 24-28 超重 / >=28 肥胖
血糖分层 pd.cut(xtsp) <100 正常 / 100-126 偏高 / >=126 糖尿病风险
高血压状态 gxy.map(BOOLEAN_LABELS) 无 / 有
心脏病状态 xzb.map(BOOLEAN_LABELS) 无 / 有
中风状态 sfzf.map(BOOLEAN_LABELS) 无 / 有
婚姻状态文本 hunyin.map(MARRIAGE_LABELS) 未婚 / 已婚
居住编码文本 residenc.map(RESIDENCE_LABELS) 中心城区 / 县城乡镇 / 村庄
风险评分 compute_risk_score() 0-100 连续值
风险等级 pd.cut(风险评分) 低/中/高/重点随访
6.3.3 过滤引擎(apply_filters)

支持多条件组合过滤:

过滤条件 参数类型 说明
age_range (min, max) 年龄范围
gender str 性别筛选
area str 城乡筛选
disease str 疾病筛选(高血压/心脏病/中风)
smoke str 吸烟状态筛选
keyword str 关键字搜索(ID、工作、吸烟状态)
6.3.4 统计分析函数
函数 输出 用途
disease_rate_frame() 五种疾病的患病率 概览图表
group_disease_rates() 按分组列统计三种疾病率 分组对比图表
disease_cooccurrence() 3x3 疾病共现矩阵 相关性分析
age_group_stats() 各年龄段综合统计 年龄分析
gender_comparison() 性别对比统计 性别分析
risk_distribution() 风险分值分布 风险分布图
generate_insights() 自动生成的文字洞察 智能分析报告
6.3.5 洞察生成(generate_insights)

自动分析数据并生成 5 类文字洞察:

  1. 样本概览: 总样本量及 60 岁以上占比
  2. 主要风险: 患病率最高的健康风险
  3. 年龄分析: 高血压比例最高的年龄段
  4. 吸烟影响: 中风占比最高的吸烟状态
  5. 综合风险: 高风险及以上样本占比
  6. 相关性分析: 与中风关联度最高的指标

6.4 app.py --- Flask Web 应用

职责: 路由处理、请求过滤、Session 管理、模板渲染。

Flask 配置:

python 复制代码
app = Flask(__name__)
app.secret_key = "health-analytics-secret-key-2024"
app.config["SESSION_TYPE"] = "filesystem"

中间件:

python 复制代码
@app.after_request
def no_cache(response):
    # 禁止浏览器缓存 HTML 页面
    response.headers["Cache-Control"] = "no-store, no-cache, must-revalidate, max-age=0"
    response.headers["Pragma"] = "no-cache"
    return response

认证装饰器:

  • @login_required --- 检查 session["user"] 是否存在,未登录则跳转 /login
  • @admin_required --- 在 login_required 基础上检查 role == "admin",非管理员重定向到 dashboard

7. 路由与接口设计

7.1 页面路由

路径 方法 权限 处理函数 说明
/ GET index() 重定向到 /dashboard
/login GET, POST login() 登录页面及表单处理
/register POST register() 用户注册
/logout GET logout() 清除 Session,退出登录
/dashboard GET 登录 dashboard() 数据总览页
/analysis GET 登录 analysis() 规律分析页
/trend GET 登录 trend() 趋势分析页
/manage GET 管理员 manage() 数据管理页
/focus GET 登录 focus() 重点关注页
/profile GET 登录 profile() 个人中心页

7.2 API 接口

7.2.1 记录管理(管理员)
路径 方法 说明 请求体
/api/records POST 新增记录 Form: addtime, xingbie, nianling, gxy, xzb, hunyin, gzxz, zzxz, xtsp, bmi, xyzk, sfzf
/api/records/<id> PUT 更新记录 JSON: 待更新字段
/api/records/<id> DELETE 删除记录
/api/import POST CSV 导入 Form: replace (checkbox)
7.2.2 关注管理(登录用户)
路径 方法 说明 请求体
/api/favorites POST 添加关注 Form: record_id, attention_level, note
/api/favorites/<id> PUT 更新关注 JSON: attention_level, note
/api/favorites/<id> DELETE 取消关注
7.2.3 用户管理
路径 方法 说明 请求体
/api/profile POST 更新资料 Form: display_name, email, phone
/api/password POST 修改密码 Form: old_password, new_password, new_password_confirm
7.2.4 数据导出
路径 方法 说明 响应
/api/export GET 导出过滤后数据 CSV 文件下载
/api/report/<id> GET 导出个人健康报告 Markdown 文件下载

7.3 通用查询参数

所有数据分析页面(dashboard、analysis、trend、manage)支持以下 URL 查询参数进行数据过滤:

参数 类型 说明 示例
age_min int 最小年龄 age_min=60
age_max int 最大年龄 age_max=80
gender str 性别 gender=男性
area str 城乡 area=城市
disease str 疾病 disease=高血压
smoke str 吸烟状态 smoke=吸烟
keyword str 关键字 keyword=私人企业
page int 页码(仅 manage) page=2

8. 前端页面设计

8.1 基础布局(base.html)

复制代码
┌─────────────────────────────────────────────────────────────┐
│ ┌──────────┐ ┌────────────────────────────────────────────┐ │
│ │          │ │                                            │ │
│ │  Logo    │ │         主内容区域                           │ │
│ │          │ │                                            │ │
│ │ 用户卡片  │ │    (各页面通过 block content 填充)            │ │
│ │          │ │                                            │ │
│ │ 导航菜单  │ │                                            │ │
│ │ ·总览     │ │                                            │ │
│ │ ·分析     │ │                                            │ │
│ │ ·趋势     │ │                                            │ │
│ │ ·管理     │ │                                            │ │
│ │ ·关注     │ │                                            │ │
│ │ ·个人中心  │ │                                            │ │
│ │          │ │                                            │ │
│ │ 退出登录  │ │                                            │ │
│ │          │ │                                            │ │
│ │ 版本信息  │ │                                            │ │
│ └──────────┘ └────────────────────────────────────────────┘ │
│   260px 固定           自适应宽度                             │
└─────────────────────────────────────────────────────────────┘

全局 JavaScript:

javascript 复制代码
// Plotly 暗色主题配置
const DARK_LAYOUT = {
    paper_bgcolor: 'rgba(0,0,0,0)',
    plot_bgcolor: 'rgba(0,0,0,0)',
    font: { color: '#e0e0e0' },
    ...
};

// 通用图表渲染函数
function plotChart(divId, data, layout = {}, config = {}) {
    Plotly.newPlot(divId, data, {...DARK_LAYOUT, ...layout}, config);
}

8.2 登录页(login.html)

  • 独立页面,不继承 base.html
  • 动画粒子背景效果
  • Bootstrap Tabs 切换登录/注册
  • 登录表单:用户名、密码
  • 注册表单:用户名、显示名、邮箱、手机号、密码、确认密码

8.3 数据总览页(dashboard.html)

布局:

复制代码
┌─────────────────────────────────────────────┐
│           顶部过滤条件栏                      │
│  [年龄范围] [性别] [城乡] [疾病] [吸烟] [搜索] │
├─────────────────────────────────────────────┤
│ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐   │
│ │总数  │ │平均  │ │平均  │ │平均  │ │高风险│   │
│ │     │ │年龄  │ │血糖  │ │BMI  │ │比例  │   │
│ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘   │
├─────────────────────────────────────────────┤
│ ┌──────────────┐ ┌──────────────────────┐   │
│ │ 健康指数仪表盘 │ │ 疾病患病率柱状图      │   │
│ └──────────────┘ └──────────────────────┘   │
│ ┌──────────────┐ ┌──────────────────────┐   │
│ │ 年龄分布直方图 │ │ 风险等级饼图          │   │
│ └──────────────┘ └──────────────────────┘   │
│ ┌──────────────┐ ┌──────────────────────┐   │
│ │ BMI-血糖散点图 │ │ 血糖箱线图            │   │
│ └──────────────┘ └──────────────────────┘   │
│ ┌──────────────┐ ┌──────────────────────┐   │
│ │ BMI分层柱状图  │ │ 城乡疾病对比          │   │
│ └──────────────┘ └──────────────────────┘   │
│ ┌──────────────┐ ┌──────────────────────┐   │
│ │ 吸烟健康影响  │ │ 婚姻状态雷达图        │   │
│ └──────────────┘ └──────────────────────┘   │
│ ┌──────────────┐ ┌──────────────────────┐   │
│ │ 工作类型疾病  │ │ 血糖/BMI分布直方图    │   │
│ └──────────────┘ └──────────────────────┘   │
└─────────────────────────────────────────────┘

包含图表类型: 仪表盘、柱状图、直方图、饼图、散点图、箱线图、雷达图(共 12+ 种)

8.4 规律分析页(analysis.html)

特色功能:

  • 自动生成的文字洞察卡片
  • 健康雷达图(四维:年龄健康、代谢指标、生活方式、疾病风险)
  • 平行坐标图(年龄、血糖、BMI、风险评分的多维关联)
  • 相关性热力图(6 个数值字段的 Pearson 相关系数矩阵)
  • 树图(风险等级 → 年龄段 → 性别的层级分布)
  • 疾病组合分析(高血压 + 心脏病 + 中风的排列组合统计)
  • BMI-血糖风险热力图(12 个象限的风险评分)
  • 高风险 Top-20 排行表
  • CSV 导出按钮

8.5 趋势分析页(trend.html)

分析维度:

  • 性别对比(柱状图 + 雷达图)
  • 年龄段疾病趋势线
  • 风险分值分布
  • 城乡差异对比
  • 年度趋势(疾病率、指标均值变化)
  • 工作类型对比
  • 婚姻状态对比
  • 吸烟状态详细分析

8.6 数据管理页(manage.html)

仅管理员访问,三个标签页:

  1. 编辑数据: 分页表格(每页 50 条),支持行内编辑和删除
  2. 新增记录: 表单录入
  3. 导入数据: CSV 同步,支持"替换模式"(清空后重新导入)

8.7 重点关注页(focus.html)

功能:

  • 添加关注(输入记录 ID、选择关注级别、填写备注)
  • 关注列表表格(支持行内修改级别和备注)
  • 跟踪详情:风险仪表盘 + 对比柱状图
  • 健康信息卡片 + 个性化健康建议
  • Markdown 格式健康报告导出

8.8 个人中心页(profile.html)

  • 用户信息卡片(头像、姓名、角色、邮箱)
  • 资料编辑表单
  • 密码修改表单

9. 数据可视化方案

9.1 技术实现

所有图表采用 Plotly.js 在客户端渲染。数据传递流程:

复制代码
Python (pandas) → dict/list → Jinja2 tojson → JavaScript JSON.parse → Plotly.js 渲染

模板中的图表渲染模式:

html 复制代码
<div id="chart-div" style="height:400px;"></div>
<script>
(function() {
    var data = {{ chart_data | tojson }};
    // 构建 Plotly traces
    plotChart('chart-div', traces, layout);
})();
</script>

9.2 图表清单

页面 图表名称 Plotly 类型 数据维度
Dashboard 健康指数仪表盘 Indicator (gauge) 综合风险评分
Dashboard 疾病患病率 Bar 5 种疾病
Dashboard 年龄分布直方图 Histogram 性别 × 年龄
Dashboard 风险等级饼图 Pie 4 个风险等级
Dashboard BMI-血糖散点图 Scatter BMI × 血糖 × 风险等级
Dashboard 血糖箱线图 Box 中风状态 × 年龄段 × 血糖
Dashboard BMI 分层柱状图 Bar 4 个 BMI 层级
Dashboard 城乡疾病对比 Bar 城乡 × 3 种疾病
Dashboard 吸烟健康影响 Bar 吸烟状态 × 多指标
Dashboard 婚姻状态雷达 Scatterpolar 婚姻 × 多维指标
Dashboard 工作类型疾病 Bar 工作类型 × 疾病率
Dashboard BMI/血糖分布 Histogram 双直方图
Analysis 健康雷达图 Scatterpolar 4 维综合评分
Analysis 年龄段疾病柱状图 Bar 年龄段 × 3 种疾病
Analysis 平行坐标 Parcoords 年龄/血糖/BMI/风险
Analysis 吸烟-中风柱状图 Bar 吸烟状态 × 中风
Analysis 相关性热力图 Heatmap 6×6 相关系数矩阵
Analysis 树图 Treemap 风险→年龄→性别
Analysis 年龄-性别-疾病 Grouped Bar 年龄段 × 性别 × 疾病
Analysis 疾病组合柱状图 Bar 疾病组合 × 人数
Analysis BMI-血糖风险热力图 Heatmap BMI × 血糖 → 风险评分
Analysis 年龄统计 Bar 均值/中位数/标准差
Analysis 风险分布 Stacked Bar 年龄段 × 风险区间
Analysis 城乡疾病对比 Grouped Bar 城乡 × 3 种疾病率
Analysis 地域指标雷达 Scatterpolar 城乡 × 多维指标
Trend 性别对比柱状图 Bar 性别 × 多指标
Trend 性别雷达图 Scatterpolar 性别 × 多维
Trend 年龄段趋势线 Scatter 年龄段 × 疾病率趋势
Trend 风险分值柱状图 Bar 年龄段 × 平均风险
Trend 血糖/趋势线 Scatter 年龄段 × 血糖趋势
Trend 城乡对比 Bar 城乡 × 多指标
Trend 年度趋势 Scatter 年份 × 指标变化
Trend 工作类型对比 Bar 工作类型 × 疾病率
Trend 婚姻对比 Bar 婚姻 × 指标
Trend 吸烟详细分析 Bar 吸烟状态 × 多指标

9.3 暗色主题

所有图表统一使用暗色主题配置:

javascript 复制代码
const DARK_LAYOUT = {
    paper_bgcolor: 'rgba(0,0,0,0)',
    plot_bgcolor: 'rgba(0,0,0,0)',
    font: { color: '#e0e0e0' },
    xaxis: { gridcolor: 'rgba(255,255,255,0.1)' },
    yaxis: { gridcolor: 'rgba(255,255,255,0.1)' },
    margin: { t: 40, r: 20, b: 40, l: 50 },
};

10. 安全机制

10.1 认证与授权

机制 实现方式
密码存储 PBKDF2-SHA256,180,000 次迭代,16 字节随机盐
密码验证 hmac.compare_digest() 防止时序攻击
会话管理 Flask Session(filesystem 存储)
路由保护 @login_required / @admin_required 装饰器
角色控制 两级角色:user(只读 + 关注)/ admin(完整 CRUD)

10.2 输入安全

机制 实现方式
SQL 注入防护 参数化查询(PyMySQL %s 占位符)
标识符验证 _quote_identifier() 正则校验 [A-Za-z0-9_]+
用户名校验 正则 [A-Za-z0-9_]{3,32}
密码强度 最少 6 位
数据类型转换 _safe_value() 统一处理空值和类型

10.3 传输安全

机制 说明
缓存控制 HTML 响应设置 no-store, no-cache
密码哈希格式 pbkdf2_sha256$iterations$salt$digest

10.4 安全注意事项

生产环境部署前需处理以下问题:

  1. app.secret_key 硬编码在源码中,应改为环境变量
  2. 数据库密码默认为 123456,应修改并使用强密码
  3. 默认管理员密码 123456 过于简单
  4. 未启用 HTTPS
  5. 未配置 CSRF Token
  6. 未设置登录失败锁定机制
  7. Flask debug 模式不应在生产环境开启

11. 部署与运行

11.1 环境要求

  • Python >= 3.8
  • MySQL >= 5.7
  • pip(Python 包管理器)

11.2 安装步骤

bash 复制代码
# 1. 克隆/解压项目
cd health

# 2. 安装 Python 依赖
pip install -r requirements.txt

# 3. 确保 MySQL 已启动
# 默认连接: localhost:3306, 用户 root, 密码 123456

# 4. 启动应用
python app.py

11.3 启动流程

python app.py 执行后:

  1. Flask 启动,监听 0.0.0.0:5000
  2. 首次请求 /dashboard 时触发 bootstrap_database()
  3. 自动创建数据库 design_132_health
  4. 自动创建 usershealth_recordstracked_people 三张表
  5. 自动插入默认管理员(admin / 123456)
  6. 自动导入 CSV 数据(4,909 条记录)

11.4 手动数据导入

bash 复制代码
# 使用 CLI 工具导入
python import_data.py

# 指定 CSV 文件
python import_data.py --csv path/to/data.csv

# 清空后重新导入
python import_data.py --reset

11.5 数据库配置覆盖

通过环境变量覆盖默认数据库配置:

bash 复制代码
export HEALTH_DB_HOST=192.168.1.100
export HEALTH_DB_PORT=3307
export HEALTH_DB_USER=health_user
export HEALTH_DB_PASSWORD=strong_password_here
export HEALTH_DB_NAME=health_db

python app.py

11.6 默认账号

角色 用户名 密码 权限
管理员 admin 123456 全部功能
普通用户 (注册) (自定义) 查看 + 关注

11.7 访问地址

启动后浏览器访问:http://localhost:5000


12. 数据字典

12.1 字段编码对照表

性别(xingbie)
含义
男性 男性
女性 女性
布尔字段(gxy / xzb / sfzf / hunyin)
含义
0 无 / 未婚
1 有 / 已婚
城乡属性(zzxz)
含义
城市 城市地区
农村 农村地区
居住编码(residenc)
含义
1 中心城区
2 县城/乡镇
3 村庄
工作性质(gzxz)
含义
私人企业 私营企业员工
自雇人士 自由职业/个体户
政府部门 政府/事业单位
儿童 未成年/儿童
吸烟状态(xyzk)
含义
从不吸烟 从未吸烟
以前吸烟 已戒烟
吸烟 当前吸烟
不详 信息缺失
BMI 分层
区间 层级 说明
< 18.5 偏瘦 体重过轻
18.5 - 24 正常 健康范围
24 - 28 超重 需关注
>= 28 肥胖 需干预
血糖分层
区间 (mg/dL) 层级 说明
< 100 正常 正常血糖
100 - 126 偏高 糖尿病前期
>= 126 糖尿病风险 建议进一步检查
关注级别(attention_level)
级别 说明
一般关注 常规跟踪
重点关注 需定期复查
高危随访 高风险,需密切监控

12.2 数据集来源


13. 已知问题与改进建议

13.1 已知问题

编号 问题 严重程度 说明
1 README 与实际不符 README 写的是 Streamlit,实际是 Flask
2 requirements.txt 包含未使用的 streamlit 不影响运行,但造成困惑
3 默认管理员密码过弱 admin/123456,生产环境需修改
4 Secret Key 硬编码 应通过环境变量配置
5 无 CSRF 保护 表单提交缺少 Token 验证
6 无登录限流 可被暴力破解
7 cookies.txt 残留 项目中遗留的无关文件
8 数据量小时全量加载 4,909 条全量加载到内存,适合中小规模

13.2 改进建议

方向 建议
安全 添加 Flask-WTF 实现 CSRF 保护;引入 Flask-Limiter 实现登录限流;使用 bcrypt 替代 PBKDF2
性能 引入 Redis 缓存热门查询结果;大数据量场景使用服务端分页;异步加载图表
功能 添加数据导出为 Excel 格式;增加数据对比功能(选择两条记录对比);添加定时报告推送
部署 使用 Gunicorn + Nginx 部署;Docker 容器化;CI/CD 自动化
代码 拆分 app.py 为 Blueprint 模块;引入 Marshmallow 进行请求参数校验;添加单元测试
前端 引入 Vue.js/React 实现 SPA;添加图表下载为图片功能;移动端适配优化

文档版本:v1.0
生成日期:2026-05-22
基于源码版本:当前工作目录

相关推荐
曹牧2 小时前
Bug定位
开发语言
linbaiwan6662 小时前
PD和QC快充协议电压诱骗(取电)芯片:USB-C口支持PD,USB-A口支持QC
c语言·开发语言
大飞记Python2 小时前
【2026更新】Python基础学习指南(AI版)——06函数
开发语言·人工智能·python
xing-xing2 小时前
Anaconda学习总结
python
我是一颗柠檬2 小时前
【JDK8新特性】函数式接口Day2
java·开发语言·后端·intellij-idea
计算机安禾2 小时前
【c++面向对象编程】第45篇:萃取(Traits)技术与策略类:STL源码中的智慧
开发语言·c++
爱吃苹果的梨叔2 小时前
2026分布式坐席系统推荐:指挥中心、调度中心、机房集中管控该怎么选?
python
liuhl09102 小时前
Python 列表推导式
python
Highcharts.js4 小时前
缺失数据可视化图表开发实战|Highcharts创建人员出生统计面积图表示例
开发语言·前端·javascript·信息可视化·highcharts·图表开发