基于Python的中国上市企业专利申请数据可视化分析系统

一个功能完整的专利数据管理与可视化分析平台,支持数据导入、智能推荐、多维度分析和用户交互

📋 目录

🎯 项目概述

本项目是一个基于Python Flask框架开发的中国上市企业专利申请数据可视化分析系统。系统集成了数据管理、智能推荐、多维度分析和用户交互等核心功能,为专利数据分析提供了完整的解决方案。

项目背景

随着中国知识产权保护意识的提升,企业专利申请数据成为衡量企业创新能力的重要指标。本系统旨在通过数据可视化和智能分析,帮助用户更好地理解和分析中国上市企业的专利申请情况。

系统定位

  • 数据管理平台:支持Excel/CSV格式的专利数据批量导入
  • 智能推荐系统:基于协同过滤算法的专利推荐
  • 可视化分析工具:多维度数据图表展示
  • 用户交互平台:支持收藏、留言等社交功能

✨ 功能特性

🔐 用户管理系统

  • 用户注册、登录、注销
  • 角色权限管理(普通用户/管理员)
  • 个人信息管理
  • 密码修改

📊 专利数据管理

  • 专利数据批量导入(支持Excel/CSV)
  • 多条件筛选和搜索
  • 专利详情查看
  • 数据分页展示

🤖 智能推荐系统

  • 基于协同过滤的专利推荐
  • "猜你喜欢"个性化推荐
  • 热门专利排行
  • 最新专利补充

💾 个人收藏系统

  • 专利收藏/取消收藏
  • 收藏列表管理
  • 收藏时间记录
  • 分页浏览

💬 留言互动系统

  • 用户留言发布
  • 管理员回复管理
  • 留言历史查看
  • 词云分析展示

📈 数据可视化分析

  • 专利申请趋势分析
  • 地区分布分析
  • 行业分布统计
  • 专利类型分布
  • 企业规模分析

🛠️ 管理后台

  • 用户管理
  • 操作日志
  • 数据导入管理
  • 留言管理

😀 项目演示

💭 项目源码获取,见博客底部联系方式卡片~
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

🏗️ 技术架构

后端技术栈

  • Web框架:Flask 2.0+
  • 数据库ORM:SQLAlchemy
  • 用户认证:Flask-Login
  • 数据处理:Pandas, openpyxl
  • 中文分词:jieba
  • 数据可视化:ApexCharts, ECharts

前端技术栈

  • 模板引擎:Jinja2
  • 样式框架:Tailwind CSS
  • JavaScript库:Vanilla JS, jQuery
  • 图表库:ApexCharts, ECharts
  • 响应式设计:移动端适配

数据库

  • 主数据库:MySQL 8.0+
  • 连接驱动:PyMySQL
  • 数据格式:支持CSV、Excel导入

开发环境

  • Python版本:3.8+
  • 包管理:pip + requirements.txt
  • 开发工具:支持热重载的Flask开发服务器

💻 核心功能实现

1. 数据导入模块

@app.route('/admin/import', methods=['GET', 'POST'])
@admin_required
def admin_import():
    if request.method == 'POST':
        if 'file' not in request.files:
            flash('请选择文件', 'error')
            return redirect(request.url)
        
        file = request.files['file']
        if file.filename == '':
            flash('请选择文件', 'error')
            return redirect(request.url)
        
        if file and allowed_file(file.filename):
            # 读取Excel文件
            df = pd.read_excel(file)
            
            # 数据清洗和验证
            for index, row in df.iterrows():
                patent = Patent(
                    company_name=row['企业名称'],
                    stock_code=row['股票代码'],
                    year=row['年份'],
                    province=row['省份'],
                    city=row['城市'],
                    industry_name=row['行业名称'],
                    patent_applications=row['专利申请数'],
                    invention_patents=row['发明专利'],
                    utility_patents=row['实用新型'],
                    apply_value=row['Apply值'],
                    iapply_value=row['IApply值'],
                    employee_count=row['员工人数'],
                    avg_salary=row['平均职工薪酬(万元)'],
                    debt_total=row['负债合计']
                )
                db.session.add(patent)
            
            db.session.commit()
            flash(f'成功导入 {len(df)} 条专利数据', 'success')
            return redirect(url_for('admin_import'))

2. 智能推荐算法

@app.route('/patents/recommend')
@login_required
def get_recommendations():
    # 获取用户收藏的专利ID
    user_favorites = Favorite.query.filter_by(user_id=current_user.id).all()
    patent_ids = [f.patent_id for f in user_favorites]
    
    if patent_ids:
        # 基于协同过滤:找到收藏了相同专利的其他用户
        similar_users = db.session.query(Favorite.user_id)\
            .filter(Favorite.patent_id.in_(patent_ids))\
            .filter(Favorite.user_id != current_user.id)\
            .group_by(Favorite.user_id)\
            .all()
        
        if similar_users:
            similar_user_ids = [u[0] for u in similar_users]
            # 获取相似用户收藏的专利
            recommended = db.session.query(Patent)\
                .join(Favorite, Patent.id == Favorite.patent_id)\
                .filter(Favorite.user_id.in_(similar_user_ids))\
                .filter(~Patent.id.in_(patent_ids))\
                .group_by(Patent.id)\
                .order_by(db.func.count(Favorite.id).desc())\
                .limit(10)\
                .all()
        else:
            recommended = []
    else:
        recommended = []
    
    # 如果推荐数量不足,补充最新专利
    if len(recommended) < 10:
        latest_patents = Patent.query\
            .filter(~Patent.id.in_([p.id for p in recommended]))\
            .order_by(Patent.year.desc(), Patent.id.desc())\
            .limit(10 - len(recommended))\
            .all()
        recommended.extend(latest_patents)
    
    return jsonify([p.to_dict() for p in recommended[:10]])

3. 数据可视化实现

@app.route('/admin/patents')
@admin_required
def admin_patents():
    # 统计数据
    total_patents = Patent.query.count()
    total_companies = Patent.query.with_entities(Patent.company_name).distinct().count()
    total_provinces = Patent.query.with_entities(Patent.province).distinct().count()
    
    # 趋势数据
    trend_data = db.session.query(
        Patent.year,
        db.func.sum(Patent.patent_applications).label('total_applications')
    ).group_by(Patent.year).order_by(Patent.year).all()
    
    # 专利类型分布
    type_data = db.session.query(
        db.func.sum(Patent.invention_patents).label('invention'),
        db.func.sum(Patent.utility_patents).label('utility')
    ).first()
    
    return render_template('admin/patents.html',
                         patents=patents,
                         pagination=pagination,
                         total_patents=total_patents,
                         total_companies=total_companies,
                         total_provinces=total_provinces,
                         trend_data=trend_data,
                         type_data=type_data)

4. 分页与搜索联动

def get_pagination_with_filters(query, page, per_page=20, **filters):
    # 应用筛选条件
    for field, value in filters.items():
        if value and hasattr(query, field):
            if isinstance(value, str):
                query = query.filter(getattr(query, field).like(f'%{value}%'))
            else:
                query = query.filter(getattr(query, field) == value)
    
    # 分页
    pagination = query.paginate(
        page=page, per_page=per_page, error_out=False
    )
    
    # 构建查询字符串(排除page参数)
    args = request.args.copy()
    args.pop('page', None)
    query_string = urllib.parse.urlencode(args)
    
    return pagination, query_string

🗄️ 数据库设计

核心表结构

-- 用户表
CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(80) UNIQUE NOT NULL,
    email VARCHAR(120) UNIQUE NOT NULL,
    password_hash VARCHAR(255) NOT NULL,
    is_admin BOOLEAN DEFAULT FALSE,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

-- 专利表
CREATE TABLE patents (
    id INT PRIMARY KEY AUTO_INCREMENT,
    company_name VARCHAR(255) NOT NULL,
    stock_code VARCHAR(20),
    year INT,
    province VARCHAR(50),
    city VARCHAR(50),
    industry_name VARCHAR(100),
    industry_code VARCHAR(20),
    listing_date DATE,
    patent_applications INT,
    invention_patents INT,
    utility_patents INT,
    apply_value DECIMAL(10,5),
    iapply_value DECIMAL(10,5),
    is_sme BOOLEAN,
    employee_count INT,
    avg_salary DECIMAL(10,5),
    debt_total DECIMAL(20,2),
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

-- 收藏表
CREATE TABLE favorites (
    id INT PRIMARY KEY AUTO_INCREMENT,
    user_id INT NOT NULL,
    patent_id INT NOT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES users(id),
    FOREIGN KEY (patent_id) REFERENCES patents(id)
);

-- 留言表
CREATE TABLE messages (
    id INT PRIMARY KEY AUTO_INCREMENT,
    user_id INT NOT NULL,
    patent_id INT,
    content TEXT NOT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES users(id),
    FOREIGN KEY (patent_id) REFERENCES patents(id)
);

-- 留言回复表
CREATE TABLE message_replies (
    id INT PRIMARY KEY AUTO_INCREMENT,
    message_id INT NOT NULL,
    user_id INT NOT NULL,
    content TEXT NOT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (message_id) REFERENCES messages(id),
    FOREIGN KEY (user_id) REFERENCES users(id)
);

🎨 前端界面设计

设计理念

  • 一致性:统一的页面布局和组件样式
  • 响应式:支持多种设备屏幕尺寸
  • 用户体验:直观的操作流程和反馈机制

核心组件

1. 统计卡片组件
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
    <div class="bg-white rounded-lg shadow p-6">
        <div class="flex items-center">
            <div class="p-3 rounded-full bg-blue-100 text-blue-600">
                <i class="fas fa-chart-line text-xl"></i>
            </div>
            <div class="ml-4">
                <p class="text-sm font-medium text-gray-600">总专利数</p>
                <p class="text-2xl font-semibold text-gray-900">{{ total_patents }}</p>
            </div>
        </div>
    </div>
    <!-- 其他统计卡片 -->
</div>
2. 筛选表单组件
<form method="GET" class="bg-white rounded-lg shadow p-6 mb-6">
    <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
        <div>
            <label class="block text-sm font-medium text-gray-700 mb-2">企业名称</label>
            <input type="text" name="company_name" value="{{ request.args.get('company_name', '') }}"
                   class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
        </div>
        <!-- 其他筛选字段 -->
    </div>
    <div class="mt-4 flex justify-end">
        <button type="submit" class="bg-blue-500 text-white px-4 py-2 rounded-md hover:bg-blue-600">
            搜索
        </button>
    </div>
</form>
3. 分页组件
<div class="flex items-center justify-between px-6 py-3 bg-white border-t border-gray-200">
    <div class="flex items-center space-x-2">
        <a href="?page=1{% if query_string %}&{{ query_string }}{% endif %}" 
           class="px-3 py-1 border border-gray-300 bg-white text-gray-500 hover:bg-gray-50 rounded-l-md">
            首页
        </a>
        {% if pagination.has_prev %}
        <a href="?page={{ pagination.prev_num }}{% if query_string %}&{{ query_string }}{% endif %}" 
           class="px-3 py-1 border border-gray-300 bg-white text-gray-500 hover:bg-gray-50">
            上一页
        </a>
        {% endif %}
        <span class="px-3 py-1 border border-gray-300 bg-blue-50 text-blue-600">
            第{{ pagination.page }}页
        </span>
        {% if pagination.has_next %}
        <a href="?page={{ pagination.next_num }}{% if query_string %}&{{ query_string }}{% endif %}" 
           class="px-3 py-1 border border-gray-300 bg-white text-gray-500 hover:bg-gray-50">
            下一页
        </a>
        {% endif %}
        <a href="?page={{ pagination.pages }}{% if query_string %}&{{ query_string }}{% endif %}" 
           class="px-3 py-1 border border-gray-300 bg-white text-gray-500 hover:bg-gray-50 rounded-r-md">
            尾页
        </a>
    </div>
</div>

🚀 部署与使用

环境要求

  • Python 3.8+
  • MySQL 8.0+
  • 现代浏览器(Chrome、Firefox、Safari、Edge)

安装步骤

  1. 克隆项目
git clone <项目地址>
cd 专利数据可视化分析系统
  1. 安装依赖
pip install -r requirements.txt
  1. 配置数据库
# config.py
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://用户名:密码@主机/数据库名'
  1. 初始化数据库
python create_table.py
  1. 运行应用
python run.py

默认账户

  • 管理员账户:admin / admin123
  • 普通用户:user / user123

🌟 项目亮点

1. 智能推荐算法

  • 基于协同过滤的个性化推荐
  • 动态补充最新专利数据
  • 实时更新推荐结果

2. 数据可视化

  • 多维度图表展示
  • 交互式数据探索
  • 美观的图表设计

3. 用户体验优化

  • 响应式设计
  • 分页与搜索联动
  • 友好的错误提示

4. 系统架构设计

  • 模块化代码结构
  • 清晰的权限管理
  • 完善的日志记录

🔧 技术难点与解决方案

1. 分页与搜索条件保持

问题:分页跳转后搜索条件丢失
解决方案:使用query_string参数传递筛选条件

# 后端构建查询字符串
args = request.args.copy()
args.pop('page', None)
query_string = urllib.parse.urlencode(args)

# 前端分页链接拼接
<a href="?page={{ pagination.next_num }}{% if query_string %}&{{ query_string }}{% endif %}">

2. 智能推荐算法优化

问题:新用户无收藏数据,推荐效果差
解决方案:混合推荐策略

  • 优先展示热门专利
  • 补充最新专利数据
  • 动态调整推荐权重

3. 大数据量处理

问题:大量专利数据导入和查询性能
解决方案

  • 数据库索引优化
  • 分页查询
  • 异步数据处理

4. 前端状态管理

问题:收藏状态同步和页面刷新
解决方案

  • 表单提交替代AJAX
  • 页面刷新保持状态
  • 统一的状态管理

📊 可视化展示预留

1. 专利申请趋势图

// 年度趋势图表
const trendChart = new ApexCharts(document.querySelector("#trendChart"), {
    chart: { type: 'line', height: 350 },
    series: [{
        name: '专利申请数',
        data: trendData
    }],
    xaxis: { categories: years },
    yaxis: { title: { text: '申请数量' } }
});

2. 地区分布图

// 省份分布饼图
const provinceChart = new ApexCharts(document.querySelector("#provinceChart"), {
    chart: { type: 'pie', height: 350 },
    series: provinceData,
    labels: provinceLabels,
    responsive: [{
        breakpoint: 480,
        options: { chart: { width: 200 } }
    }]
});

3. 词云展示

// 留言内容词云
const wordCloud = echarts.init(document.getElementById('wordCloud'));
const option = {
    series: [{
        type: 'wordCloud',
        shape: 'circle',
        left: 'center',
        top: 'center',
        width: '70%',
        height: '80%',
        data: wordData
    }]
};

📈 项目总结

技术收获

  1. Flask框架深度应用:掌握了Flask的完整开发流程
  2. 数据库设计优化:学会了复杂查询和性能优化
  3. 前端交互设计:提升了用户体验设计能力
  4. 算法实现:实践了推荐算法的工程化应用

功能完整性

  • ✅ 用户管理系统
  • ✅ 数据管理功能
  • ✅ 智能推荐系统
  • ✅ 可视化分析
  • ✅ 社交互动功能
  • ✅ 管理后台

可扩展性

  • 支持更多数据源导入
  • 可集成更多推荐算法
  • 支持更多可视化图表
  • 可扩展移动端应用

📞 联系方式

码界筑梦坊 各平台同名 - 专注技术分享与项目开发
见博客底部联系方式卡片咨询源码


本文详细介绍了基于Python的中国上市企业专利申请数据可视化分析系统的开发过程和技术实现。项目采用Flask框架,集成了智能推荐、数据可视化、用户管理等核心功能,为专利数据分析提供了完整的解决方案。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐