中药药材数据可视化分析系统 --- 技术文档
一、项目概述
本系统是一套基于 Python + Vue3 的中药药材数据可视化分析平台,涵盖药材数据管理、百科知识库、产地地图、关系图谱、多维度统计分析、报告导出等功能。系统采用前后端分离架构,支持用户注册登录、权限管理及后台管理。
二、技术栈
2.1 后端技术栈
技术
版本
用途
Python
3.10+
主语言
Django
4.2.8
Web 框架(仅用作路由层和中间件,不使用 ORM)
Django REST Framework
3.14.0
RESTful API 序列化/视图装饰器
PyMySQL
1.1.0
MySQL 数据库驱动(原生 SQL 操作)
PyJWT
2.8.0
JWT 令牌签发与验证
Passlib + bcrypt
1.7.4 / 4.1.2
密码哈希与校验
Pandas
2.1.4
数据处理与分析
NumPy
1.26.2
数值计算
scikit-learn
1.3.2
机器学习(聚类、异常检测)
SciPy
1.11.4
统计检验(t 检验、ANOVA、卡方检验)
statsmodels
0.14.1
回归分析、时间序列分解与 ARIMA 预测
mlxtend
0.23.0
关联规则挖掘(Apriori 算法)
ReportLab
4.0.8
PDF 报告生成(支持中文字体)
openpyxl
3.1.2
Excel 报告生成
PyYAML
6.0.1
配置文件解析
django-cors-headers
4.3.1
跨域请求支持
2.2 前端技术栈
技术
版本
用途
Vue 3
^3.4.0
前端框架(Composition API + <script setup> 语法)
TypeScript
^5.3.0
类型安全
Vite
^5.0.0
构建工具与开发服务器
Vue Router
^4.3.0
前端路由
Pinia
^2.1.0
状态管理
Element Plus
^2.6.0
UI 组件库
ECharts
^5.5.0
数据可视化图表
Axios
^1.6.0
HTTP 请求
NProgress
^0.2.0
路由切换进度条
2.3 数据库
项目
说明
数据库
MySQL 5.7+ / 8.0
数据库名
design_93_tcm
字符集
utf8mb4 + utf8mb4_unicode_ci
连接方式
PyMySQL 原生连接(非 Django ORM)
2.4 开发与运行环境
项目
说明
操作系统
Windows 11
后端端口
8000(Django 开发服务器)
前端端口
5173(Vite 开发服务器)
API 代理
Vite proxy 将 /api 和 /uploads 转发至后端
三、系统架构
3.1 整体架构
复制代码
┌─────────────────┐ HTTP/API ┌─────────────────────┐
│ │ ←──────────────→ │ │
│ Vue3 前端 │ Vite Proxy │ Django 后端 │
│ (Port 5173) │ /api → :8000 │ (Port 8000) │
│ │ /uploads → :8000 │ │
└─────────────────┘ └──────────┬──────────┘
│
│ PyMySQL (Raw SQL)
│
┌─────┴─────┐
│ MySQL │
│ design_93 │
│ _tcm │
└───────────┘
3.2 后端架构
复制代码
backend/
├── config/ # Django 配置模块
│ ├── settings.py # 项目设置(从 config.yaml 读取数据库配置)
│ ├── urls.py # 顶层 URL 路由分发
│ └── wsgi.py # WSGI 入口
├── apps/ # 业务应用模块
│ ├── users/ # 用户认证与管理
│ │ ├── views.py # 登录/注册/个人信息/头像上传/密码修改/管理员接口
│ │ └── urls.py # /api/auth/* 路由
│ ├── herbs/ # 药材与百科
│ │ ├── views.py # 药材CRUD/百科CRUD/关系图谱/产地地图/大屏数据/配置接口
│ │ └── urls.py # /api/herbs/*, /api/encyclopedia/*, /api/graph/*, /api/geo/*
│ ├── news/ # 新闻与消息
│ │ ├── views.py # 新闻CRUD/点赞/收藏/站内消息
│ │ └── urls.py # /api/news/*, /api/messages/*
│ └── analytics/ # 数据分析
│ ├── views.py # 数据概览/专题分析/统计检验/回归/时序/关联规则/报告导出
│ └── urls.py # /api/analytics/*, /api/timeseries/*, /api/association/*, /api/reports/*
├── shared/ # 核心分析引擎(纯 Python,框架无关)
│ ├── analysis_core.py # 基础数据分析(分布、相关性、交叉分析)
│ ├── stats_core.py # 统计检验(描述性统计、正态性、t检验、ANOVA、卡方)
│ ├── regression_core.py # 回归分析(线性回归、多元回归、回归诊断)
│ ├── anomaly_core.py # 异常检测(IQR、Z-Score、Isolation Forest)
│ ├── comparative_core.py # 同比环比分析(时段对比、增长趋势)
│ ├── clustering_core.py # 聚类分析(K-Means、DBSCAN)
│ ├── timeseries_core.py # 时间序列(分解、ARIMA 预测、季节性)
│ ├── association_core.py # 关联规则(Apriori 频繁项集挖掘)
│ └── report_core.py # 报告导出(Excel + PDF 自动生成)
├── database.py # 数据库操作层(所有 SQL 查询集中管理)
├── config.yaml # 项目配置文件(数据库、数据集、模块开关、分析参数)
├── data/ # 数据集文件
│ ├── 中医药数据.csv # 主数据集(500条药材数据,24个字段)
│ └── hurbTable.csv # 百科数据集(780+条百科词条,17个字段)
├── uploads/ # 用户上传文件目录
│ └── avatars/ # 头像文件
├── reports/ # 生成的报告文件目录
├── model/ # 模型文件目录(预留)
├── run.py # 一键启动脚本(依赖检查 + 数据库初始化 + 服务启动)
├── manage.py # Django 管理命令入口
└── requirements.txt # Python 依赖列表
3.3 前端架构
复制代码
frontend/
├── src/
│ ├── api/ # API 请求模块(按业务域拆分)
│ │ ├── auth.ts # 登录/注册/个人信息
│ │ ├── herbs.ts # 药材列表/详情
│ │ ├── encyclopedia.ts # 百科 CRUD
│ │ ├── news.ts # 新闻/点赞/收藏
│ │ ├── messages.ts # 站内消息
│ │ ├── analytics.ts # 数据分析接口
│ │ ├── dashboard.ts # 大屏概览数据
│ │ ├── geo.ts # 产地地图
│ │ ├── graph.ts # 关系图谱
│ │ └── admin.ts # 管理员接口
│ ├── views/
│ │ ├── portal/ # 前台页面
│ │ │ ├── Home.vue # 系统首页(搜索、推荐药材、最新新闻)
│ │ │ ├── HerbList.vue # 中药百科列表
│ │ │ ├── HerbDetail.vue # 药材详情(基本信息、百科、统计)
│ │ │ ├── GeoMap.vue # 产地地图(ECharts 中国地图 + 省份下钻)
│ │ │ ├── RelationGraph.vue # 关系图谱(力导向图)
│ │ │ ├── NewsList.vue # 新闻列表
│ │ │ ├── NewsDetail.vue # 新闻详情
│ │ │ ├── Profile.vue # 个人中心(信息编辑、头像上传、修改密码)
│ │ │ ├── Messages.vue # 消息中心
│ │ │ └── Bookmarks.vue # 我的收藏
│ │ ├── analytics/ # 数据分析页面
│ │ │ ├── Overview.vue # 数据概览(统计卡片 + 可视化图表)
│ │ │ ├── AnalyticsPage.vue # 通用专题分析(动态路由,按 config 渲染)
│ │ │ ├── TimeSeries.vue # 时间序列分析
│ │ │ ├── Association.vue # 关联规则分析
│ │ │ └── Reports.vue # 报告导出
│ │ ├── admin/ # 后台管理页面
│ │ │ ├── Dashboard.vue # 管理面板
│ │ │ ├── Users.vue # 用户管理
│ │ │ ├── HerbManage.vue # 药材管理(CRUD + CSV 导入)
│ │ │ ├── EncyclopediaManage.vue # 百科管理
│ │ │ └── NewsManage.vue # 新闻管理
│ │ ├── auth/ # 认证页面
│ │ │ ├── Login.vue # 登录
│ │ │ └── Register.vue # 注册
│ │ └── dashboard/ # 数据大屏
│ │ └── BigScreen.vue # 全屏数据可视化大屏
│ ├── components/
│ │ └── Layout.vue # 主布局(侧边栏导航 + 内容区)
│ ├── stores/
│ │ ├── user.ts # 用户状态管理(Pinia)
│ │ └── config.ts # 系统配置状态管理(分析页面、字段映射等)
│ ├── utils/
│ │ └── request.ts # Axios 实例(统一请求/响应拦截、JWT Token 注入)
│ ├── assets/styles/
│ │ └── global.css # 全局样式(CSS 变量、主题色)
│ ├── App.vue # 应用根组件
│ └── main.ts # 应用入口
├── index.html # HTML 模板
├── vite.config.ts # Vite 配置(别名、代理)
├── tsconfig.json # TypeScript 配置
├── tsconfig.node.json # Node 环境 TypeScript 配置
├── package.json # 依赖清单
└── env.d.ts # 类型声明
四、数据库表结构设计
4.1 用户表 users
字段
类型
约束
说明
id
INT
PRIMARY KEY, AUTO_INCREMENT
主键
username
VARCHAR(50)
UNIQUE, NOT NULL
用户名
email
VARCHAR(100)
邮箱
password_hash
VARCHAR(200)
NOT NULL
密码哈希(bcrypt)
avatar
VARCHAR(500)
DEFAULT ''
头像 URL
role
ENUM('user','admin')
DEFAULT 'user'
角色
status
ENUM('active','disabled')
DEFAULT 'active'
账号状态
last_login_at
DATETIME
最后登录时间
created_at
DATETIME
DEFAULT NOW()
注册时间
4.2 药材数据表 herbs
字段
类型
说明
id
INT (PK)
主键
药材编号
VARCHAR(20)
药材唯一编号
中药名称
VARCHAR(50)
药材中文名
功效分类
VARCHAR(50)
功效大类(如:清热药、补血药)
性质
VARCHAR(20)
药性(温/平/寒/热/凉等)
味道
VARCHAR(50)
药味(甘/苦/辛等)
归经
VARCHAR(100)
归经信息
主要功效
VARCHAR(50)
主要药理功效
适应症
VARCHAR(50)
适用症状
用量_克
DOUBLE
推荐用量(克)
价格_元每克
DOUBLE
单价(元/克)
价格等级
VARCHAR(20)
价格分级(低/中/高/特高)
产地
VARCHAR(50)
主产地省份
采收季节
VARCHAR(20)
采收时间
保质期_月
INT
保质期(月)
质量等级
VARCHAR(20)
质量分级(特等/一等/二等/三等/统货)
库存量_公斤
INT
当前库存(公斤)
年销量_公斤
INT
年销量(公斤)
供应商名称
VARCHAR(50)
供应商
供应商评分
DOUBLE
供应商评分(3.8-5.0)
炮制方法
VARCHAR(20)
炮制工艺
毒性等级
VARCHAR(20)
毒性分级(无毒/小毒/有毒)
批次号
VARCHAR(20)
生产批次号
检验报告号
VARCHAR(30)
质检报告编号
录入日期
DATE
数据录入日期
更新日期
DATE
数据更新日期
created_at
DATETIME
记录创建时间
4.3 百科知识表 encyclopedia
字段
类型
说明
id
INT (PK)
主键
Name
VARCHAR(100)
中药名称
Medicine_Name
VARCHAR(200)
药材名
Alias
TEXT
别名
English_Name
VARCHAR(200)
英文名称
Medicinal_Part
TEXT
药用部位
Source
TEXT
来源
Morphology
TEXT
形态特征
Distribution
TEXT
产地分布
Processing
TEXT
采收加工
Properties
TEXT
药材性状
Type
VARCHAR(200)
性味归经
Effect
TEXT
功效主治
Usage
TEXT
用法用量
Constituent
TEXT
化学成分
Formula
TEXT
方剂配伍
Pharmacology
TEXT
药理作用
Taboo
TEXT
使用禁忌
created_at
DATETIME
记录创建时间
4.4 新闻资讯表 news
字段
类型
约束
说明
id
INT
PK, AUTO_INCREMENT
主键
title
VARCHAR(200)
NOT NULL
标题
summary
TEXT
摘要
content
LONGTEXT
正文(HTML)
cover_image
VARCHAR(500)
DEFAULT ''
封面图 URL
author_id
INT
作者用户 ID
status
ENUM('draft','published')
DEFAULT 'published'
发布状态
views
INT
DEFAULT 0
浏览次数
likes_count
INT
DEFAULT 0
点赞数
bookmarks_count
INT
DEFAULT 0
收藏数
created_at
DATETIME
DEFAULT NOW()
创建时间
updated_at
DATETIME
DEFAULT NOW()
更新时间
4.5 新闻点赞表 news_likes
字段
类型
约束
说明
id
INT
PK, AUTO_INCREMENT
主键
user_id
INT
NOT NULL
用户 ID
news_id
INT
NOT NULL
新闻 ID
created_at
DATETIME
DEFAULT NOW()
点赞时间
UNIQUE(user_id, news_id)
联合唯一约束
4.6 新闻收藏表 news_bookmarks
字段
类型
约束
说明
id
INT
PK, AUTO_INCREMENT
主键
user_id
INT
NOT NULL
用户 ID
news_id
INT
NOT NULL
新闻 ID
created_at
DATETIME
DEFAULT NOW()
收藏时间
UNIQUE(user_id, news_id)
联合唯一约束
4.7 站内消息表 messages
字段
类型
约束
说明
id
INT
PK, AUTO_INCREMENT
主键
sender_id
INT
NOT NULL
发送者用户 ID
receiver_id
INT
NOT NULL
接收者用户 ID
title
VARCHAR(200)
消息标题
content
TEXT
消息内容
is_read
TINYINT
DEFAULT 0
是否已读(0=未读, 1=已读)
created_at
DATETIME
DEFAULT NOW()
发送时间
4.8 ER 关系说明
复制代码
users(1) ──── news_likes(N) ───── news(1)
│ │
│ news_bookmarks(N) ─────┘
│
├──── messages(N) [sender_id / receiver_id]
│
└──── news(N) [author_id]
herbs ←── CSV 导入(中医药数据.csv)
encyclopedia ←── CSV 导入(hurbTable.csv)
五、API 接口设计
5.1 认证模块 /api/auth/
方法
路径
说明
认证
POST
/api/auth/login
用户登录,返回 JWT Token
否
POST
/api/auth/register
用户注册
否
GET
/api/auth/profile
获取当前用户信息
是
PUT
/api/auth/profile
更新个人信息(邮箱/头像)
是
PUT
/api/auth/password
修改密码
是
POST
/api/auth/upload_avatar
上传头像文件
是
5.2 药材模块 /api/herbs/
方法
路径
说明
认证
GET
/api/herbs
药材列表(分页、搜索、筛选)
否
POST
/api/herbs
新增药材
管理员
GET
/api/herbs/{id}
药材详情
否
PUT
/api/herbs/{id}
更新药材
管理员
DELETE
/api/herbs/{id}
删除药材
管理员
POST
/api/herbs/import_csv
CSV 批量导入
管理员
5.3 百科模块 /api/encyclopedia/
方法
路径
说明
认证
GET
/api/encyclopedia
百科列表(分页、搜索、分类筛选)
否
POST
/api/encyclopedia
新增百科词条
管理员
GET
/api/encyclopedia/{id}
百科详情
否
PUT
/api/encyclopedia/{id}
更新百科词条
管理员
DELETE
/api/encyclopedia/{id}
删除百科词条
管理员
GET
/api/encyclopedia/categories
百科分类列表
否
5.4 新闻模块 /api/news/
方法
路径
说明
认证
GET
/api/news
新闻列表(分页、搜索)
否
POST
/api/news
发布新闻
管理员
GET
/api/news/{id}
新闻详情(自动+1浏览量)
否
PUT
/api/news/{id}
编辑新闻
管理员
DELETE
/api/news/{id}
删除新闻
管理员
POST
/api/news/{id}/like
点赞/取消点赞
是
POST
/api/news/{id}/bookmark
收藏/取消收藏
是
GET
/api/news/my_bookmarks
我的收藏列表
是
5.5 消息模块 /api/messages/
方法
路径
说明
认证
GET
/api/messages
消息列表
是
POST
/api/messages
发送消息
是
GET
/api/messages/unread
未读消息计数
是
PUT
/api/messages/{id}/read
标记已读
是
DELETE
/api/messages/{id}
删除消息
是
5.6 数据分析模块 /api/analytics/
方法
路径
说明
GET
/api/analytics/overview
数据概览(统计摘要、分布、相关性)
GET
/api/analytics/{page_route}
专题分析(根据 config.yaml 中 analysis_pages 动态路由)
支持的专题页面(page_route):
efficacy --- 功效分类分析
property --- 药性分析
price --- 价格分析
origin --- 产地分布分析
quality --- 质量库存分析
supplier --- 供应商分析
processing --- 炮制与毒性分析
statistical --- 统计检验(ANOVA、卡方、t检验)
regression --- 回归分析(线性回归、回归诊断)
anomaly --- 异常检测
comparative --- 同比环比分析
5.7 时间序列模块 /api/timeseries/
方法
路径
说明
POST
/api/timeseries/decompose
时间序列分解(趋势、季节性、残差)
POST
/api/timeseries/forecast
ARIMA 预测
5.8 关联规则模块 /api/association/
方法
路径
说明
POST
/api/association/rules
Apriori 关联规则挖掘
5.9 报告模块 /api/reports/
方法
路径
说明
GET
`/api/reports/generate?export_format=pdf
excel`
GET
/api/reports/list
已生成报告列表
5.10 其他接口
方法
路径
说明
GET
/api/config
获取系统配置(字段映射、分析页面列表等)
GET
/api/graph/relationships
药材关系图谱数据
GET
/api/geo/province_distribution
各省药材分布统计
GET
/api/geo/province_detail/{province}
省份药材详情
GET
/api/dashboard/overview
大屏概览数据
GET
/api/admin/dashboard
管理后台统计
GET
/api/admin/users
用户列表(管理员)
PUT
/api/admin/users/{id}/status
禁用/启用用户
DELETE
/api/admin/users/{id}
删除用户
六、核心技术实现
6.1 认证机制
系统采用 JWT(JSON Web Token) 认证,不依赖 Django 自带的 Session 认证系统。
令牌签发 :用户登录成功后,服务端使用 PyJWT 签发 JWT,有效期 7 天
令牌载荷 :user_id、username、role、exp(过期时间)、iat(签发时间)
令牌验证 :每个需认证的接口通过 get_user_from_token() 从 Authorization: Bearer xxx 头部解析令牌
密码安全 :使用 passlib + bcrypt 进行密码哈希存储,不存明文
前端存储 :Token 存储在 Pinia store(内存)+ localStorage 持久化
6.2 数据库操作层
系统不使用 Django ORM ,所有数据库操作通过 database.py 中的 Database 类以原生 SQL 执行:
每次操作独立获取连接,操作完成后立即释放(短连接模式)
批量插入使用 executemany,每批 100-500 条
查询结果以 DictCursor 返回字典格式
分页查询在 SQL 层做 LIMIT/OFFSET,避免全量查询
6.3 配置驱动
系统核心配置集中在 config.yaml,实现配置驱动的动态功能:
数据集定义 :字段名、类型、范围、可选值
模块开关 :通过 modules 节点控制功能模块的启用/禁用
分析页面 :通过 analysis_pages 配置专题分析页面,前端动态渲染
字段映射 :field_mapping 提供中英文字段对照
分析参数 :关联规则的支持度/置信度阈值、聚类列、时序列等
前端通过 /api/config 接口获取配置,Pinia configStore 管理全局状态。
6.4 数据分析引擎
分析引擎位于 shared/ 目录,每个模块是纯 Python 类,不依赖任何 Web 框架:
模块
核心功能
analysis_core.py
数据概览统计、字段分布、相关性矩阵、交叉分析
stats_core.py
描述性统计、正态性检验(Shapiro-Wilk)、t 检验、单因素 ANOVA、卡方独立性检验
regression_core.py
简单线性回归、多元线性回归、R²/F 统计量、残差分析、VIF 共线性检验
anomaly_core.py
IQR 方法、Z-Score 方法、Isolation Forest 算法
comparative_core.py
按时段聚合、同比增长率、环比增长率、移动平均
clustering_core.py
K-Means 聚类(肘部法自动选 K)、DBSCAN 密度聚类、聚类画像
timeseries_core.py
时间序列分解(加法/乘法)、ARIMA 预测、ACF/PACF
association_core.py
Apriori 算法频繁项集挖掘、关联规则提取(支持度/置信度/提升度)
report_core.py
Excel 报告(openpyxl)、PDF 报告(ReportLab + 中文字体)
路由层数据转换 :shared/ 模块返回的数据结构与前端期望格式可能不同,路由层(views.py)负责桥接转换,包括键名重命名、结构扁平化、类型转换等。
6.5 ECharts 可视化
前端使用 ECharts 5.5 实现所有数据可视化图表:
图表类型 :柱状图、折线图、饼图、散点图、雷达图、热力图、力导向图、中国地图、桑基图
中国地图 :注册 GeoJSON 数据,支持省份下钻(懒加载省份 GeoJSON)
关系图谱 :力导向图展示药材间的功效、产地、归经关系
响应式 :使用 ResizeObserver 监听容器尺寸变化自动 resize
主题一致 :各页面统一使用 chartColors 配色数组,与系统主题色 #2D6A4F(草本绿)保持一致
6.6 报告导出
PDF 报告 :使用 ReportLab 生成,支持中文字体(系统字体 .ttc 文件 + subfontIndex)
5 个章节:数据概览、描述性统计、相关性矩阵、分类分布、数据样本
所有表格单元格使用 Paragraph 对象确保中文渲染
表格样式含表头配色(#2D6A4F)、斑马条纹、自动换行
Excel 报告 :使用 openpyxl 生成,包含多个 Sheet
数据概览 Sheet、描述性统计 Sheet、原始数据 Sheet
6.7 文件上传
头像上传 :前端使用 el-upload 组件的 http-request 自定义上传方法
通过 Axios 实例发送请求(自动携带 JWT Token)
后端校验文件类型(jpg/png/gif/webp)和大小(≤2MB)
文件以 UUID 命名存储到 uploads/avatars/ 目录
Django 通过 re_path 配置静态文件服务
6.8 前端路由与权限
路由守卫 :router.beforeEach 全局守卫
meta.auth = true:需登录,未登录重定向到 /login
meta.role = 'admin':需管理员角色
meta.guest = true:仅未登录可访问(已登录重定向首页)
动态菜单 :侧边栏根据用户角色动态显示管理菜单
路由进度条 :NProgress 在路由切换时显示顶部进度条
6.9 核心算法实现详解
6.9.1 Apriori 关联规则挖掘
算法流程 :
复制代码
1. 数据预处理:将分类字段独热编码(One-Hot Encoding)
encoded = pd.get_dummies(df[valid_cols].astype(str), prefix_sep="=")
2. 频繁项集挖掘:迭代搜索所有满足最小支持度的项集
- 1-项集 → 剪枝 → 2-项集 → 剪枝 → ... → K-项集
- 支持度 = 项集出现次数 / 总事务数
3. 关联规则生成:从频繁项集生成满足最小置信度的规则
- 置信度 = P( consequents | antecedents )
- 提升度 = 置信度 / consequents 支持度(>1 表示正相关)
核心代码(association_core.py):
freq_items = apriori(encoded, min_support=min_support, use_colnames=True)
rules = association_rules(freq_items, num_itemsets=len(freq_items),
metric="confidence", min_threshold=min_confidence)
参数调优建议 :
min_support:推荐 0.01~0.05,数据稀疏时适当降低
min_confidence:推荐 0.3~0.7,过高规则过少,过低噪音大
max_unique:限制唯一值数量(默认 50),避免维度灾难
6.9.2 ARIMA 时间序列预测
模型阶数选择 :
复制代码
1. ADF 平稳性检验:
- p-value < 0.05:序列平稳,直接建模
- p-value >= 0.05:序列非平稳,需差分处理
2. ACF/PACF 分析确定 (p, q):
- PACF 截尾位置 → p(自回归阶数)
- ACF 截尾位置 → q(移动平均阶数)
3. AIC/BIC 准则:在候选模型中选取信息量最小者
核心代码(timeseries_core.py):
model = ARIMA(series, order=(p, d, q))
fitted = model.fit()
forecast = fitted.forecast(steps=forecast_periods)
conf_int = fitted.get_forecast(steps=forecast_periods).conf_int()
分解模型 (加法/乘法):
复制代码
加法模型:Y(t) = T(t) + S(t) + R(t)
乘法模型:Y(t) = T(t) × S(t) × R(t)
其中:T(t)=趋势分量,S(t)=季节分量,R(t)=残差分量
季节周期通过参数指定(如 12 个月)
6.9.3 Isolation Forest 异常检测
算法原理 :
复制代码
- 异常点在随机划分的特征空间中更容易被隔离
- 构造多棵孤立树(iTree),计算每个点的平均路径长度
- 路径越短 → 越可能是异常点
核心代码(anomaly_core.py):
from sklearn.ensemble import IsolationForest
clf = IsolationForest(contamination=0.05, random_state=42, n_estimators=100)
clf.fit(data[features])
predictions = clf.predict(data[features]) # -1=异常, 1=正常
scores = clf.decision_function(data[features]) # 异常分数
参数说明 :
contamination:预计异常比例,推荐 0.01~0.1
n_estimators:树的数量(默认 100),越多越稳定
max_samples:每棵树采样的样本数(默认 auto)
6.9.4 K-Means 聚类分析
算法流程 :
复制代码
1. 选择 K 个初始质心(K-Means++ 优化:使初始质心尽可能分散)
2. 分配:将每个点分配到最近的质心,形成 K 个簇
3. 更新:重新计算每个簇的质心(均值)
4. 迭代:重复步骤 2、3,直到质心不再变化或达到最大迭代次数
肘部法(Elbow Method)自动选 K:
for k in range(2, 10):
model = KMeans(n_clusters=k, random_state=42)
model.fit(data)
inertias.append(model.inertia_) # 簇内误差平方和
# 在 inertia 曲线拐点处选择 K
核心代码(clustering_core.py):
from sklearn.cluster import KMeans
model = KMeans(n_clusters=k, init='k-means++', random_state=42, n_init=10)
labels = model.fit_predict(data[features])
centers = model.cluster_centers_
6.9.5 DBSCAN 密度聚类
与 K-Means 对比 :
特性
K-Means
DBSCAN
簇形状
球形
任意形状
离群点
强制分配
识别为噪声
参数
K(需预设)
eps, min_samples
复杂度
O(n)
O(n²)
核心代码 :
python
复制代码
from sklearn.cluster import DBSCAN
model = DBSCAN(eps=0.5, min_samples=5)
labels = model.fit_predict(data[features])
# labels: -1 表示噪声点,0,1,2... 表示簇编号
七、设计风格
7.1 配色方案
CSS 变量
色值
用途
--primary
#2D6A4F
主题色(草本绿)
--primary-light
#52B788
浅主题色
--primary-dark
#1B4332
深主题色(侧边栏背景)
--bg-main
#F0F2F5
主内容区背景
--text-primary
#2D3A2E
正文文字
--text-secondary
#6B7B6E
次要文字
7.2 UI 组件
基于 Element Plus 组件库,全局按需引入
侧边栏:深色背景固定导航,支持折叠/展开
卡片/表格:圆角 + 微阴影,统一间距
八、部署与运行
8.1 环境要求
Python 3.10+
Node.js 18+
MySQL 5.7+ / 8.0
8.2 后端启动
bash
复制代码
cd code/backend
pip install -r requirements.txt
python run.py
run.py 会自动完成:
检查并安装依赖
初始化数据库(建表 + 创建默认管理员 + 导入 CSV 数据)
启动 Django 开发服务器(0.0.0.0:8000)
默认管理员账号:admin / admin123
8.3 前端启动
bash
复制代码
cd code/frontend
npm install
npm run dev
开发服务器启动在 http://localhost:5173,Vite 代理自动转发 API 请求到后端。
8.4 生产部署
bash
复制代码
# 前端构建
cd code/frontend
npm run build
# 产出 dist/ 目录,部署到 Nginx
# 后端
# 使用 Gunicorn/uWSGI 替代 Django 开发服务器
gunicorn config.wsgi:application --bind 0.0.0.0:8000
九、项目目录结构(清理后)
复制代码
code/
├── backend/ # 后端项目
│ ├── apps/ # Django 应用(4个业务模块)
│ │ ├── analytics/ # 数据分析
│ │ ├── herbs/ # 药材与百科
│ │ ├── news/ # 新闻与消息
│ │ └── users/ # 用户认证
│ ├── config/ # Django 配置
│ ├── shared/ # 核心分析引擎(8个分析模块 + 报告导出)
│ ├── data/ # 数据集文件(2个 CSV)
│ ├── uploads/ # 用户上传文件
│ ├── reports/ # 生成的报告(运行时产生)
│ ├── model/ # 模型文件(预留)
│ ├── database.py # 数据库操作层
│ ├── config.yaml # 项目配置
│ ├── run.py # 一键启动脚本
│ ├── manage.py # Django 管理入口
│ └── requirements.txt # Python 依赖
├── frontend/ # 前端项目
│ ├── src/
│ │ ├── api/ # API 模块(10个)
│ │ ├── views/ # 页面组件(20个)
│ │ ├── components/ # 公共组件
│ │ ├── stores/ # 状态管理(2个)
│ │ ├── utils/ # 工具函数
│ │ └── assets/ # 静态资源
│ ├── vite.config.ts # Vite 配置
│ └── package.json # 依赖清单
├── data/ # 原始数据集(备份)
│ ├── hurbTable.csv # 百科数据(780+条)
│ └── 中医药数据.csv # 药材数据(500条)
└── docs/ # 项目文档
├── spec.md # 项目规格书
├── api.md # API 接口文档
├── design-system.md # 设计系统规范
└── dev-rules.md # 开发规范
十、项目成果截图展示
系统经过完整测试,所有页面截图保存于 docs/screenshots/ 目录:
截图文件
页面说明
验证结果
home.png
系统首页(搜索栏、推荐药材、最新资讯轮播、统计卡片)
✅ 正常
herbs.png
药材百科列表(卡片/表格双视图切换、分类筛选)
✅ 正常
map.png
中国地图产地分布(ECharts 中国地图 + 省份下钻)
⚠️ 需地图服务
graph.png
关系图谱(力导向图、节点分类、点击详情)
✅ 正常
news.png
新闻列表(封面图、摘要、点赞收藏)
✅ 正常
login.png
登录页(表单验证、JWT Token 认证)
✅ 正常
register.png
注册页(密码确认、重复注册校验)
✅ 正常
dashboard.png
数据大屏(全屏可视化、多个 ECharts 图表)
✅ 正常
analytics_overview.png
数据分析概览(统计卡片、分布图、相关性热力图)
✅ 正常
timeseries.png
时序分析(时间序列分解、ARIMA 预测图)
✅ 正常
association.png
关联规则(Apriori 算法结果表格)
✅ 正常
reports.png
报告导出(Excel/PDF 双格式下载)
✅ 正常
⚠️ 注:map.png 地图页面空白,是因为 ECharts 中国地图 GeoJSON 数据需要从外部 CDN 加载,需确保网络通畅或内网部署时替换为本地 GeoJSON 文件。
十一、数据完整处理流程
11.1 数据导入流程
复制代码
CSV 文件(中医药数据.csv / hurbTable.csv)
↓
run.py 初始化脚本
↓
database.py 批量导入(每批 100 条)
↓
MySQL 数据库(design_93_tcm)
↓
药材表(herbs)/ 百科表(encyclopedia)
批量导入核心代码 (database.py ):
python
复制代码
def batch_insert(self, table, records, batch_size=100):
if not records:
return
keys = list(records[0].keys())
cols = ', '.join(keys)
placeholders = ', '.join(['%s'] * len(keys))
sql = f"INSERT INTO {table} ({cols}) VALUES ({placeholders})"
for i in range(0, len(records), batch_size):
batch = [tuple(r.get(k) for k in keys) for r in records[i:i+batch_size]]
with self.get_connection() as conn:
conn.cursor().executemany(sql, batch)
conn.commit()
11.2 数据分析流程
复制代码
前端请求(如 /api/analytics/efficacy)
↓
views.py 接收参数(分页、筛选条件)
↓
从 database.py 获取原始数据
↓
调用 shared/analysis_core.py(纯 Python 分析)
↓
返回 dict/list 结构
↓
views.py 转换为前端期望格式
↓
JSON 响应返回前端
↓
ECharts 渲染图表
11.3 关系图谱构建流程
复制代码
encyclopedia 表(780+ 条百科数据)
↓
提取 Formula(方剂配伍)字段
↓
在 Formula 中匹配药材名称(长度 >= 2 的精确匹配)
↓
同一 Formula 中的药材两两建立共现关系
↓
边权重 = 共现次数(同一 Formula 出现多次则累加)
↓
从 Effect(功效)字段提取类别前缀作为节点分类
↓
力导向图布局(ECharts force graph)
十二、环境变量与配置参考
12.1 config.yaml 完整结构
yaml
复制代码
# 项目信息
project:
name: 中药药材数据可视化分析系统
version: 1.0.0
# 数据库配置
database:
host: localhost
port: 3306
user: root
password: root
name: design_93_tcm
charset: utf8mb4
# 数据集配置
data:
herb_csv: data/中医药数据.csv
encyclopedia_csv: data/hurbTable.csv
# 功能模块开关
modules:
association_rules: true
time_series: true
regression: true
anomaly_detection: true
clustering: true
comparative: true
statistical_tests: true
# 关联规则参数
association:
min_support: 0.01
min_confidence: 0.2
columns: [功效分类, 性质, 味道, 产地, 质量等级]
# 聚类分析配置
clustering:
n_clusters: 3
features: [价格_元每克, 用量_克, 供应商评分]
# 时序分析配置
time_series:
date_column: 录入日期
value_column: 年销量_公斤
frequency: M # 月度
12.2 前端环境变量
env
复制代码
VITE_API_BASE_URL=http://localhost:8000
VITE_APP_TITLE=中药药材数据可视化分析系统
十三、常见问题排查
问题
可能原因
解决方案
地图页面空白
GeoJSON CDN 无法访问
替换为本地 GeoJSON 文件
关联规则报错 association_rules() missing num_itemsets
mlxtend 版本过新(>=0.21)
添加 num_itemsets=len(freq_items) 参数
CSV 导入失败
编码问题(中文列名)
使用 encoding='utf-8-sig' 读取 CSV
图表不渲染
ECharts 未正确注册地图
确认 echarts.registerMap('china', geoJSON) 已调用
JWT Token 过期
默认 7 天过期
修改 JWT_EXPIRATION_DELTA 或前端 refresh
报告 PDF 中文乱码
系统字体缺失
安装中文字体或指定 fontName 参数