基于 Flask 的电商超市数据可视化分析系统 — 技术文档 目录 项目概述 技术栈 项目结构 系统架构 数据库设计 后端路由设计 数据分析引擎 前端页面设计 API 接口文档 用户认证与权限 管理后台 部署与运行 依赖清单 1. 项目概述 本系统是一个基于 Flask 框架的电商超市数据可视化分析平台,通过对超市销售数据的多维度分析,提供销售趋势、产品分析、客户画像、时间序列、地理分布和数据挖掘等六大分析模块,共 45 个分析方法,生成 47 种图表,帮助管理者做出数据驱动的经营决策。
核心功能:
用户登录注册与权限管理(管理员/普通用户) 数据总览仪表盘(8 个 KPI 指标卡片 + 6 个概览图表) 六大分析模块(销售/产品/客户/时间/地理/数据挖掘) 管理后台(用户管理 + 销售数据 CRUD) 个人中心(头像上传、信息编辑、密码修改) 2. 技术栈 层级 技术 版本 用途 后端框架 Flask 3.0.0 Web 应用框架 ORM Flask-SQLAlchemy 3.1.1 数据库操作 认证 Flask-Login 0.6.3 用户会话管理 数据库 SQLite — 数据持久化存储 数据分析 pandas 2.1.4 数据加载、清洗、聚合 数据分析 numpy 1.26.2 数值计算 前端模板 Jinja2 — 服务端页面渲染 图表库 ECharts 5.x 数据可视化(主要) UI 框架 Bootstrap 4.x 页面布局与组件 图标库 Font Awesome 4.x 图标 JS 库 jQuery 3.x DOM 操作、AJAX 服务端 Werkzeug 3.0.1 WSGI 工具库
3. 项目结构 code/ ├── app.py # 主应用入口:路由定义、数据库初始化 ├── config.py # 配置类(密钥、数据库路径、数据文件路径) ├── requirements.txt # Python 依赖清单 ├── 技术文档.md # 本文档 │ ├── models/ # 数据模型层 │ ├── __init__.py # db 实例创建 + 模型导入 │ ├── user.py # User 模型(用户表) │ └── sales.py # SalesData 模型(销售数据表) │ ├── utils/ # 工具层 │ ├── __init__.py │ └── data_analyzer.py # SalesAnalyzer 类(45 个分析方法) │ ├── data/ # 数据文件 │ ├── sales_data.csv # 主数据源(UTF-8-sig 编码) │ ├── 超市销售分析.xls # 原始 Excel 数据 │ └── supermarket.db # SQLite 数据库文件(自动生成) │ ├── templates/ # Jinja2 模板(12 个文件) │ ├── base.html # 基础布局(侧边栏、头部、底部、CSS/JS 引入) │ ├── dashboard.html # 数据总览页 │ ├── auth/ │ │ ├── login.html # 登录页 │ │ └── register.html # 注册页 │ ├── profile/ │ │ └── index.html # 个人中心页 │ ├── admin/ │ │ └── dashboard.html # 管理后台页(用户管理 + 数据管理) │ ├── sales/ │ │ └── analysis.html # 销售分析页(8 图表) │ ├── product/ │ │ └── analysis.html # 产品分析页(8 图表) │ ├── customer/ │ │ └── analysis.html # 客户分析页(8 图表) │ ├── time/ │ │ └── analysis.html # 时间分析页(9 图表) │ ├── geo/ │ │ └── analysis.html # 地理分析页(8 图表) │ └── mining/ │ └── analysis.html # 数据挖掘页(6 图表) │ └── static/ # 静态资源 ├── css/ # 17 个 CSS 文件 │ ├── bootstrap.min.css # Bootstrap 4 │ ├── style.css # moban 模板主样式 │ └── custom.css # 自定义覆盖样式 ├── js/ # 61 个 JS 文件 │ ├── echarts.min.js # ECharts 图表库 │ ├── jquery.min.js # jQuery │ ├── bootstrap.min.js # Bootstrap JS │ └── main.js # 自定义 JS(菜单、计数器动画) └── img/ # 图片资源 ├── logo.png # 侧边栏 Logo ├── admin.jpg # 默认头像 └── auth-bg.jpg # 登录注册背景图4. 系统架构 4.1 三层架构 ┌─────────────────────────────────────────────────────┐ │ 前端展示层 │ │ Jinja2 模板 + Bootstrap + ECharts + jQuery AJAX │ │ 用户浏览器渲染页面,通过 AJAX 调用 API 获取图表数据 │ └───────────────────────┬─────────────────────────────┘ │ HTTP (GET/POST) ┌───────────────────────┴─────────────────────────────┐ │ 后端路由层 │ │ app.py: 22 个页面路由 + 6 个 API 路由族 │ │ 处理请求、调用分析方法、返回 JSON 或渲染模板 │ └───────────────────────┬─────────────────────────────┘ │ ┌───────────────┴───────────────┐ │ │ ┌───────┴────────┐ ┌─────────┴──────────┐ │ 数据分析层 │ │ 数据持久层 │ │ SalesAnalyzer │ │ SQLAlchemy ORM │ │ pandas + numpy│ │ SQLite 数据库 │ │ 45 个分析方法 │ │ User / SalesData │ │ 读取 CSV │ │ 读写 DB │ └────────────────┘ └────────────────────┘4.2 数据流 页面加载 :浏览器请求页面路由 → Flask 渲染 Jinja2 模板返回 HTML图表加载 :页面 JS 通过fetch('/api/<module>/<chart_type>')请求 API数据处理 :API 路由调用SalesAnalyzer对应方法 → pandas 计算 → 返回 JSON图表渲染 :前端 JS 将 JSON 数据传入 ECharts 配置渲染图表4.3 关键设计模式 懒加载单例 :SalesAnalyzer在首次 API 调用时初始化,将 CSV 全量加载到内存 DataFrame,后续调用复用同一实例路由分发模式 :每个 API 路由族使用data_map字典将 URL 中的chart_type参数映射到具体的分析方法AJAX 异步加载 :分析页面 HTML 只包含图表容器,图表数据通过 AJAX 独立加载,互不阻塞5. 数据库设计 5.1 User 表(users) 字段 类型 约束 说明 id Integer 主键,自增 用户 ID username String(80) UNIQUE, NOT NULL 用户名 email String(120) UNIQUE, NOT NULL 邮箱 password_hash String(256) NOT NULL 密码哈希(werkzeug) avatar String(200) DEFAULT ‘img/default-avatar.png’ 头像路径 role String(20) DEFAULT ‘user’ 角色:user / admin phone String(20) DEFAULT ‘’ 手机号 created_at DateTime SERVER DEFAULT now() 注册时间
方法:
set_password(password)— 生成密码哈希check_password(password)— 验证密码is_admin()— 判断是否管理员5.2 SalesData 表(sales_data) 字段 类型 对应 CSV 列名 说明 id Integer — 主键,自增 order_id String(50) 订单编号 订单唯一标识 order_date String(20) 订货日期 订货日期字符串 ship_date String(20) 发货日期 发货日期字符串 ship_mode String(50) 邮寄方式 标准/二级/一级/当日 customer_id String(50) 客户ID 客户唯一标识 customer_name String(100) 客户名称 客户姓名 segment String(50) 细类 消费者/公司/家庭办公 city String(100) 城市 城市名 province String(100) 省/自治区 省级行政区 country String(100) 国家 国家名 region String(50) 地区 东/南/西/北/中 product_id String(100) 产品ID 产品唯一标识 category String(50) 大类 家具/办公用品/技术 sub_category String(50) 子类 书架/椅子/电话 等 product_name String(200) 产品名称 产品完整名称 sales Float 销售额 销售金额 quantity Integer 数量 购买数量 discount Float 折扣 折扣率 (0~1) profit Float 利润 利润金额(可为负)
5.3 初始化逻辑 应用启动时执行init_db():
创建所有表(db.create_all()) 若users表为空,插入两个默认用户:admin / admin123(角色:admin)user / user123(角色:user) 若sales_data表为空,从data/sales_data.csv批量导入数据(每批 1000 条) 6. 后端路由设计 6.1 认证路由 路由 方法 函数 说明 /loginGET, POST login()登录页面。POST 验证用户名密码,登录成功重定向到/ /registerGET, POST register()注册页面。POST 创建新用户(默认角色 user) /logoutGET logout()退出登录,重定向到/login
6.2 页面路由(需登录) 路由 函数 说明 /dashboard()数据总览,传递 6 组统计数据给模板 /salessales_analysis()销售分析页(图表通过 AJAX 加载) /productproduct_analysis()产品分析页 /customercustomer_analysis()客户分析页 /timetime_analysis()时间分析页 /geogeo_analysis()地理分析页 /miningmining_analysis()数据挖掘页 /profileprofile()个人中心页
6.3 API 路由(需登录,返回 JSON) 路由模式 函数 图表类型参数 /api/sales/<chart_type>api_sales()scatter, ship_mode, discount_impact, segment, quarterly, subcategory, city_top, heatmap /api/product/<chart_type>api_product()category_pie, subcategory_detail, product_top, quantity_dist, category_discount, price_range, profit_rate, product_trend /api/customer/<chart_type>api_customer()segment_pie, value_tiers, region_dist, frequency, scatter, retention, segment_monthly, value_heatmap /api/time/<chart_type>api_time()year_quarter_heatmap, monthly_prediction, growth_rate, shipping, year_compare, weekday, hourly, cumulative, seasonal /api/geo/<chart_type>api_geo()province_map, region_pie, province_profit, city_top, region_trend, province_quantity, region_profit_compare, logistics /api/mining/<chart_type>api_mining()rfm, basket, profit_prediction, clv, clusters, anomaly
6.4 用户路由(需登录) 路由 方法 函数 说明 /profile/updatePOST profile_update()更新用户名、邮箱、手机号、头像 /profile/passwordPOST change_password()修改密码(验证旧密码)
6.5 管理路由(需管理员权限) 路由 方法 函数 说明 /adminGET admin_dashboard()管理后台(用户列表 + 分页数据列表) /admin/user/delete/<id>POST admin_delete_user()删除用户(不可删自己) /admin/user/role/<id>POST admin_change_role()修改用户角色 /admin/data/addPOST admin_data_add()添加销售数据 /admin/data/edit/<id>POST admin_data_edit()编辑销售数据 /admin/data/delete/<id>POST admin_data_delete()删除销售数据
7. 数据分析引擎 7.1 SalesAnalyzer 类 文件: utils/data_analyzer.py
初始化: __init__(self, csv_path)— 读取 CSV 文件,计算派生列(年份、月份、季度、发货天数),存入内存 DataFrame。
单例获取: 通过get_analyzer()函数懒加载,全局只初始化一次。
7.2 分析方法清单(45 个) 数据总览(6 个方法) 方法 返回结构 说明 get_overview_stats()Dict 总销售额、总利润、总订单数、客户总数、产品数量、平均客单价、平均折扣、利润率 get_yearly_sales()List[Dict] 按年汇总:年份、销售额、利润、订单数 get_monthly_sales()List[Dict] 按月汇总:月份(period)、销售额、利润 get_region_sales()List[Dict] 按地区汇总:地区、销售额、利润、订单数(降序) get_category_sales()List[Dict] 按大类汇总:大类、销售额、利润、数量 get_top_products(n)List[Dict] 销售额 Top N 产品:产品名称、销售额、利润、数量
销售分析(8 个方法) 方法 返回结构 说明 get_sales_profit_scatter()List[Dict] 散点图数据(最多 2000 条采样):销售额、利润、大类、折扣 get_ship_mode_analysis()List[Dict] 按邮寄方式:邮寄方式、销售额、利润、订单数、平均发货天数 get_discount_impact()List[Dict] 折扣影响:折扣、平均销售额、平均利润、订单数 get_segment_analysis()List[Dict] 按细类:细类、销售额、利润、客户数、平均订单金额 get_quarterly_trend()List[Dict] 季度趋势:年季(如"2023Q1")、销售额、利润 get_subcategory_rank()List[Dict] 子类排名:子类、销售额、利润、数量(升序) get_city_top(n)List[Dict] Top N 城市:城市、销售额、利润 get_monthly_heatmap()List[Dict] 月度热力图:年份、月份、销售额
产品分析(8 个方法) 方法 返回结构 说明 get_category_pie()List[Dict] 大类占比:大类、销售额 get_subcategory_detail()List[Dict] 子类明细:大类、子类、销售额、利润、数量 get_product_top(n)List[Dict] Top N 产品:产品名称、销售额、利润、数量 get_quantity_dist()List[Dict] 数量分布:数量、订单数、销售额 get_category_discount()List[Dict] 大类折扣:大类、平均折扣、最大折扣、折扣订单比例 get_price_range_dist()List[Dict] 价格区间分布:价格区间、订单数、总利润 get_profit_rate_by_category()List[Dict] 大类利润率:大类、销售额、利润、利润率 get_product_trend()List[Dict] 产品趋势:年份、大类、销售额
客户分析(8 个方法) 方法 返回结构 说明 get_customer_segment_pie()List[Dict] 细类占比:细类、销售额 get_customer_value_tiers()List[Dict] 价值分层:价值层级、客户数、平均消费、平均订单数(5 层:<1k, 1k-5k, 5k-10k, 10k-50k, >50k) get_customer_region_dist()List[Dict] 地区分布:地区、客户数、销售额 get_purchase_frequency()List[Dict] 购买频次:频次区间、客户数(5 个区间) get_customer_scatter()List[Dict] 散点图(最多 500 条):客户ID、总销售额、总利润、细类 get_customer_retention()List[Dict] 留存分析:年份、留存客户数、留存率 get_segment_monthly()List[Dict] 细类月度:月份、细类、销售额 get_customer_value_heatmap()List[Dict] 热力图:地区、细类、销售额
时间分析(9 个方法) 方法 返回结构 说明 get_year_quarter_heatmap()List[Dict] 年-季度热力图:年份、季度、销售额 get_monthly_trend_with_prediction()List[Dict] 月度趋势+预测:月份、销售额、is_prediction(含 6 个月线性回归预测) get_growth_rate()List[Dict] 增长率:年份、销售额、增长率(YoY%) get_shipping_analysis()List[Dict] 发货分析:邮寄方式、平均发货天数、订单数 get_year_comparison()List[Dict] 年度对比:年份、销售额、利润、订单数、客户数 get_weekday_analysis()List[Dict] 星期分布:星期、销售额、订单数 get_hourly_pattern()List[Dict] 月度模式:月份、销售额、订单数 get_cumulative_sales()List[Dict] 累计趋势:月份、销售额、累计销售额 get_seasonal_decomposition()List[Dict] 季节指数:月序号、销售额、季节指数
地理分析(8 个方法) 方法 返回结构 说明 get_province_sales_map()List[Dict] 省级销售地图:省/自治区、销售额、利润、订单数 get_region_pie()List[Dict] 地区占比:地区、销售额 get_province_profit_map()List[Dict] 省级利润地图:省/自治区、利润、利润率 get_city_top_geo(n)List[Dict] Top N 城市:城市、地区、销售额、利润 get_region_trend()List[Dict] 地区趋势:月份、地区、销售额 get_province_quantity()List[Dict] 省级数量:省/自治区、数量、平均数量 get_region_profit_compare()List[Dict] 地区利润对比:地区、大类、销售额、利润 get_logistics_efficiency()List[Dict] 物流效率:地区、邮寄方式、平均发货天数、订单数
数据挖掘(6 个方法) 方法 返回结构 说明 get_rfm_analysis()List[Dict] RFM 分群:客户分群、客户数、平均消费、平均频率(4 类:重要价值/发展/保持/挽留客户) get_market_basket()List[Dict] 购物篮分析:类别1、类别2、共现次数 get_profit_prediction_data()List[Dict] 利润预测数据:月份、销售额、利润、订单数、平均折扣、月份序号 get_customer_lifetime_value()List[Dict] 客户终身价值(最多 500 条):客户ID、总销售额、CLV、订单数、月均消费 get_sales_pattern_clusters()List[Dict] 聚类数据(最多 300 条):大类、总销售额、总利润、平均折扣、销售数量(标准化值) get_anomaly_detection()Dict 异常检测:normal(最多 200 条)和anomalies(最多 50 条),含 Z 分数(阈值 |z| > 2.5)
8. 前端页面设计 8.1 基础布局(base.html) 侧边栏导航结构:
分组 菜单项 图标 路由 — 数据总览 fa-laptop / 数据分析 销售分析 fa-line-chart /sales 数据分析 产品分析 fa-cube /product 数据分析 客户分析 fa-users /customer 数据分析 时间分析 fa-clock-o /time 数据分析 地理分析 fa-map-marker /geo 高级分析 数据挖掘 fa-database /mining 系统管理 个人中心 fa-user /profile 系统管理 管理后台 fa-cog /admin(仅管理员可见)
头部区域: Logo、菜单折叠按钮、页面标题、实时时钟、用户头像下拉菜单(个人中心、退出登录)
CSS/JS 加载链:
normalize.min.css → bootstrap.min.css → font-awesome.min.css → themify-icons.css → pe-icon-7-stroke.min.css → style.css → custom.css echarts.min.js → jquery.min.js → popper.min.js → bootstrap.min.js → main.js8.2 数据总览页(dashboard.html) KPI 卡片(8 个,两行):
第一行:总销售额、总利润、总订单数、客户总数 第二行:平均客单价、产品数量、平均折扣、利润率 图表(6 个):
月度销售趋势(双 Y 轴折线图:销售额 + 利润) 销售额 TOP10 产品(水平条形图) 品类销售占比(环形饼图) 年度销售对比(分组柱状图) 地区销售分布(柱状图) 8.3 分析页面模板 每个分析页面遵循统一模式:
页面 HTML 只包含图表容器<div id="chart-xxx" class="chart-container"> {% block extra_js %}中定义loadChart(url, callback)函数每个图表通过loadChart('/api/<module>/<type>', function(data) { ... })异步加载 回调函数中初始化 ECharts 实例、设置 option、绑定 resize 事件 8.4 图表配色方案 颜色 色值 用途 主色(金色) #d4943a 销售额、主要指标 绿色 #67C23A 利润、正值 橙色 #F5A623 辅助指标 红色 #D0021B 负值、预警 紫色 #ab8ce4 辅助系列
8.5 登录注册页 超市背景图片(static/img/auth-bg.jpg)+ 半透明黑色遮罩 白色卡片居中,绿色顶部条(#00c292) Bootstrap 标准表单组件 注册页含密码强度指示器(弱/中等/强) 9. API 接口文档 9.1 通用规则 认证: 所有 API 需要登录(@login_required),未登录返回 302 重定向到/login请求方式: GET响应格式: JSON数据来源: SalesAnalyzer实例方法错误处理: 无效的chart_type返回{"error": "无效的图表类型"},HTTP 4009.2 API 调用示例 // 前端调用模式 function loadChart ( url, cb ) { fetch ( url) . then ( r => r. json ( ) ) . then ( cb) . catch ( e => console. error ( e) ) ; } // 使用 loadChart ( '/api/sales/scatter' , function ( data ) { var chart= echarts. init ( document. getElementById ( 'chart-scatter' ) ) ; chart. setOption ( { // ECharts 配置... series : [ { data : data. map ( d => [ d[ '销售额' ] , d[ '利润' ] ] ) } ] } ) ; } ) ; 9.3 API 返回示例 GET/api/time/growth_rate
[ { "年份" : 2020 , "销售额" : 2299900.86 , "增长率" : null } , { "年份" : 2021 , "销售额" : 2574078.43 , "增长率" : 11.92 } , { "年份" : 2022 , "销售额" : 2950065.87 , "增长率" : 14.60 } , { "年份" : 2023 , "销售额" : 3276097.04 , "增长率" : 11.05 } ] 10. 用户认证与权限 10.1 认证机制 使用Flask-Login管理用户会话 密码使用werkzeug.security的generate_password_hash/check_password_hash(PBKDF2 算法) Session 密钥配置在config.py的SECRET_KEY 10.2 权限模型 角色 权限 普通用户 (user) 查看所有分析页面、编辑个人信息、修改密码 管理员 (admin) 普通用户全部权限 + 管理后台(用户管理 + 数据 CRUD)
10.3 权限检查 页面路由:@login_required装饰器 管理路由:@login_required+current_user.is_admin()手动检查 前端侧边栏:{% if current_user.is_admin() %}控制管理后台链接可见性 11. 管理后台 11.1 用户管理 用户列表表格(显示 ID、用户名、邮箱、手机号、角色、注册时间) 角色切换:下拉选择框直接提交表单 删除用户:带确认弹窗,不可删除自己 11.2 数据管理 Tab 切换界面(用户管理 / 数据管理) 数据列表:分页显示(每页 20 条),含 ID、订单编号、客户、产品名称、大类、地区、销售额、利润 添加数据:模态框表单(19 个字段) 编辑数据:模态框表单(自动回填当前值) 删除数据:带确认弹窗 利润正数显示绿色,负数显示红色 11.3 Tab 状态保持 操作(添加/编辑/删除/翻页)后通过 URL 参数?tab=data保持在数据管理 Tab。
12. 部署与运行 12.1 环境准备 # 克隆项目后进入 code 目录 cd code# 安装依赖 pipinstall -r requirements.txt12.2 启动应用 python app.py启动时自动:
创建 SQLite 数据库表 插入默认用户(admin/user) 从 CSV 导入销售数据 在http://localhost:5003启动服务 12.3 默认账号 用户名 密码 角色 admin admin123 管理员 user user123 普通用户
12.4 配置说明 编辑config.py可修改:
SECRET_KEY— Session 密钥(生产环境应更换)SQLALCHEMY_DATABASE_URI— 数据库连接字符串DATA_FILE— CSV 数据文件路径13. 依赖清单 requirements.txt Flask==3.0.0 Flask-Login==0.6.3 Flask-SQLAlchemy==3.1.1 pandas==2.1.4 numpy==1.26.2 scikit-learn==1.3.2 xlrd==2.0.1 Werkzeug==3.0.1前端 CDN 依赖(本地已包含) 库 版本 文件 jQuery 3.x static/js/jquery.min.jsBootstrap 4.x static/css/bootstrap.min.css+static/js/bootstrap.min.jsECharts 5.x static/js/echarts.min.jsFont Awesome 4.x static/css/font-awesome.min.cssPopper.js 1.x static/js/popper.min.js