python3.10.6+flask+sqlite开发一个越南留学中国网站的流程与文件组织结构说明

采用python3.10.6+flask+sqlite技术栈,开发一个越南留学中国网站(vietnam-study-in-china)。开发流程与文件组织结构说明

一、项目概述与规划

(一)项目背景与意义

  1. 留学趋势分析

    近年来,中越两国教育交流日益频繁,越南学生赴华留学人数逐年增长。据教育部统计,2023 年越南在华留学生数量突破 5 万人,涵盖基础教育、高等教育、语言培训等多个领域。然而,当前针对越南学生的赴华留学信息平台存在信息分散、语言不通、流程不透明等问题,导致越南学生获取准确留学信息的成本较高。

  2. 项目价值

    本项目 "vietnam-study-in-china"(越南留学中国网)旨在搭建一个集信息查询、院校展示、申请指导、在线咨询于一体的综合性平台,通过中越双语服务消除语言障碍,整合中国高校资源与留学政策,为越南学生提供 "一站式" 赴华留学解决方案,同时助力中国高校拓展越南招生市场。

  3. 项目目标

    • 打造越南学生赴华留学的核心信息枢纽,覆盖 80% 以上越南赴华留学生的信息查询需求;
    • 接入至少 200 所中国高校的招生信息,实现院校专业、录取要求、奖学金政策等信息的实时更新;
    • 提供智能化申请流程指导,将越南学生的留学申请材料准备时间缩短 50%;
    • 建立中越双语在线咨询系统,响应时间不超过 24 小时。

(二)技术栈选型分析

  1. 核心技术栈确定

    本项目采用 "Python 3.10.6 + Flask + SQLite" 技术栈,选择依据如下:

    • Python 3.10.6:作为主流编程语言,具备语法简洁、生态丰富的特点,3.10.6 版本支持结构化模式匹配(match-case)、更优的错误提示等特性,提升开发效率;
    • Flask :轻量级 Web 框架,灵活性高,适合中小型项目快速开发,其模块化设计便于功能扩展,且拥有丰富的扩展库(如 Flask-SQLAlchemy、Flask-Login 等);
    • SQLite :嵌入式关系型数据库,无需独立服务器,适合初期数据量较小的场景,且与 Python 兼容性极佳,后期可平滑迁移至 MySQL 或 PostgreSQL。
  2. 辅助技术与工具

    • 前端技术:HTML5、CSS3、JavaScript(ES6+)、Bootstrap 5(响应式框架)、jQuery(简化 DOM 操作);
    • 模板引擎 :Jinja2(Flask 默认模板引擎,支持模板继承、变量替换、条件判断等);
    • ORM 工具 :Flask-SQLAlchemy(简化数据库操作,实现对象与关系的映射);
    • 认证授权:Flask-Login(用户会话管理)、Flask-WTF(表单处理与验证);
    • 部署工具:Waitress(Windows 环境下的 WSGI 服务器)、Gunicorn(Linux 环境备选);
    • 开发工具 :PyCharm(IDE)、Git(版本控制)、Postman(API 测试)、SQLiteStudio(数据库管理)。

(三)开发团队与分工

  1. 团队架构(5 人团队)

    • 项目经理(1 人):负责项目整体规划、进度管理、需求对接;
    • 后端开发工程师(2 人):负责 Flask 框架搭建、数据库设计、API 开发、业务逻辑实现;
    • 前端开发工程师(1 人):负责页面设计、响应式布局、交互功能开发;
    • 测试与运维工程师(1 人):负责系统测试、部署配置、服务器维护。
  2. 职责分工明细

    • 项目经理:制定里程碑计划(如需求分析完成、原型设计完成、Alpha 版本发布等),每周组织进度评审会,协调跨部门资源;
    • 后端工程师 A:负责用户模块(注册、登录、权限管理)、数据库模型设计;
    • 后端工程师 B:负责院校模块、资讯模块、申请流程模块的开发;
    • 前端工程师:根据 UI 设计稿实现页面,对接后端 API,优化用户体验;
    • 测试与运维工程师:编写测试用例(单元测试、集成测试),搭建测试环境,部署生产环境并监控系统运行。

(四)项目时间规划(总周期 12 周)

  1. 第一阶段:需求分析与设计(2 周)

    • 第 1 周:完成用户需求调研、需求文档撰写、竞品分析;
    • 第 2 周:完成系统架构设计、数据库设计、UI 原型设计。
  2. 第二阶段:核心功能开发(6 周)

    • 第 3-4 周:搭建开发环境、实现用户模块与基础框架;
    • 第 5-6 周:开发院校信息展示、搜索与筛选功能;
    • 第 7-8 周:开发留学资讯、申请指南、在线咨询功能。
  3. 第三阶段:测试与优化(2 周)

    • 第 9 周:单元测试、集成测试、功能测试,修复发现的 BUG;
    • 第 10 周:性能优化(页面加载速度、数据库查询效率)、兼容性测试(多浏览器、多设备)。
  4. 第四阶段:部署与上线(2 周)

    • 第 11 周:服务器环境配置、域名绑定、SSL 证书部署;
    • 第 12 周:数据初始化、灰度发布、上线后监控与问题修复。

二、需求分析

(一)用户需求分析

  1. 目标用户群体

    • 核心用户:越南籍学生(15-30 岁),包括高中生(申请本科)、本科生(申请硕士)、在职人员(申请语言培训或短期交流);
    • 次要用户:中国高校招生办工作人员、留学中介机构、越南学生家长。
  2. 用户需求细分

    • 信息获取需求:查询中国高校名单、专业设置、录取分数线、学费标准、奖学金政策、签证流程等;
    • 交互需求:在线咨询留学问题、下载申请材料模板、查看成功案例、与其他越南留学生交流;
    • 功能需求:中越双语切换、院校对比、申请进度查询、个性化推荐(根据成绩、专业意向推荐院校)。
  3. 用户场景示例

    • 场景 1:越南高中生 Nguyen 希望申请中国的计算机专业本科,通过网站查询开设该专业的高校,筛选学费低于 5 万元 / 年的院校,并下载申请表格;
    • 场景 2:中国某大学招生老师登录后台,发布 2024 年越南招生计划,并回复学生的咨询留言;
    • 场景 3:越南学生家长通过网站的 "家长指南" 板块,了解学生在华生活注意事项及住宿安排。

(二)功能需求分析

  1. 前台功能模块

    • 首页:轮播图(展示热门院校、留学政策)、快捷入口(院校查询、申请指南、资讯动态)、数据统计(在华越南留学生人数、合作院校数量);
    • 院校库:按地区(如北京、上海、广东)、层次(本科、硕士、语言学校)、专业分类展示院校,支持关键词搜索与筛选,院校详情页包含简介、专业设置、招生要求、联系方式;
    • 留学资讯:政策解读(中国留学签证政策、奖学金政策)、院校动态(招生通知、开放日信息)、留学攻略(申请流程、材料准备、生活指南),支持按时间、类别筛选;
    • 申请中心:申请流程指引、材料清单下载、在线咨询入口、申请进度查询(需登录);
    • 用户中心:注册 / 登录、个人信息管理、收藏的院校 / 资讯、咨询记录、消息通知。
  2. 后台功能模块

    • 用户管理:查看用户列表、审核用户身份(如高校认证)、禁用违规账号;
    • 内容管理:发布 / 编辑 / 删除院校信息、资讯文章,上传图片与附件,管理评论与留言;
    • 数据统计:访问量统计、用户注册量统计、热门院校排名、咨询问题分类统计;
    • 系统设置:网站基本信息配置(名称、LOGO、联系方式)、权限管理(分配管理员角色)、数据备份与恢复。
  3. 非功能需求

    • 性能:页面加载时间≤3 秒,支持同时在线用户≥500 人;
    • 安全性:用户密码加密存储、敏感操作需二次验证、防止 SQL 注入与 XSS 攻击;
    • 易用性:界面简洁直观,中越双语切换流畅,操作步骤不超过 3 步即可完成核心需求;
    • 可扩展性:预留 API 接口,便于后期对接高校招生系统、支付系统等第三方平台。

(三)需求文档输出

  1. 需求规格说明书(SRS)

    包含项目概述、功能需求(用例图 + 用例描述)、非功能需求、数据需求等,示例用例描述如下:

    • 用例名称:查询院校信息
    • 参与者:未登录用户、已登录用户
    • 前置条件:用户访问网站首页
    • 基本流程:
      1. 用户点击 "院校库" 入口;
      2. 系统展示院校筛选条件(地区、专业、层次);
      3. 用户选择筛选条件并提交;
      4. 系统显示符合条件的院校列表;
      5. 用户点击某一院校,系统展示该院校详情页。
    • 异常流程:若筛选条件无匹配结果,系统提示 "未找到符合条件的院校,请调整筛选条件"。
  2. 原型设计(Axure RP 输出)

    包括前台页面原型(首页、院校列表页、详情页、用户中心等)和后台页面原型(管理员登录页、内容管理页等),标注页面元素、交互逻辑、跳转关系。

  3. 数据字典

    定义核心数据实体及属性,例如:

    • 实体 "用户":用户 ID(主键)、用户名、密码(加密)、邮箱、国籍、身份类型(学生 / 高校 / 中介)、注册时间、状态(正常 / 禁用);
    • 实体 "院校":院校 ID(主键)、名称(中文 / 越南语)、地区、层次、简介、联系方式、合作状态(已认证 / 待审核)。

三、系统设计

(一)架构设计

  1. 整体架构(三层架构)

    • 表现层:负责用户交互与页面展示,包括 HTML 页面、CSS 样式、JavaScript 脚本,通过 Jinja2 模板引擎与后端数据交互;
    • 业务逻辑层:处理核心业务逻辑,包括用户认证、数据验证、院校信息处理等,通过 Flask 视图函数实现;
    • 数据访问层:负责数据的存储与读取,通过 SQLAlchemy ORM 与 SQLite 数据库交互,隐藏底层数据库操作细节。
  2. 技术架构图

    复制代码
    客户端(浏览器)
         ↓↑
    Web服务器(Waitress)
         ↓↑
    Flask应用
    ├─ 蓝图(用户模块、院校模块、资讯模块等)
    ├─ 扩展(SQLAlchemy、Login、WTF等)
    └─ 业务逻辑处理
         ↓↑
    SQLite数据库
  3. 模块间交互流程

    以 "用户查询院校信息" 为例:

    1. 用户在浏览器输入查询条件并提交请求;
    2. 请求经 Web 服务器转发至 Flask 应用的院校模块蓝图;
    3. 业务逻辑层验证请求参数,调用数据访问层查询符合条件的院校数据;
    4. 数据访问层通过 SQLAlchemy 执行数据库查询,返回结果至业务逻辑层;
    5. 业务逻辑层将数据传递给表现层,Jinja2 模板渲染页面并返回给用户。

(二)接口设计

  1. 接口设计原则

    • 遵循 RESTful 规范,使用 HTTP 方法表示操作类型(GET 查询、POST 创建、PUT 更新、DELETE 删除);

    • 接口 URL 采用名词复数形式(如/api/universities表示院校相关接口);

    • 统一返回格式,包含状态码(code)、消息(message)、数据(data),例如:

      复制代码
      {
        "code": 200,
        "message": "查询成功",
        "data": [{"id": 1, "name": "北京大学", ...}]
      }
  2. 核心 API 接口列表

    • 用户模块
      • POST /api/users/register:用户注册
      • POST /api/users/login:用户登录
      • GET /api/users/profile:获取个人信息(需登录)
    • 院校模块
      • GET /api/universities:查询院校列表(支持分页、筛选)
      • GET /api/universities/{id}:获取院校详情
      • POST /api/universities/{id}/collect:收藏院校(需登录)
    • 资讯模块
      • GET /api/news:查询资讯列表
      • GET /api/news/{id}:获取资讯详情
    • 咨询模块
      • POST /api/consultations:提交咨询问题
      • GET /api/consultations/my:查询个人咨询记录(需登录)
  3. 接口权限控制

    • 公开接口:无需登录即可访问(如院校列表、资讯详情);
    • 登录接口:需验证用户身份(如个人信息、收藏功能);
    • 管理员接口:需管理员权限(如发布资讯、管理用户),通过 Flask 的@admin_required装饰器实现。

(三)安全设计

  1. 用户认证与授权

    • 采用 Flask-Login 管理用户会话,登录状态存储在加密的 Cookie 中,有效期 7 天;
    • 密码通过 Werkzeug 的generate_password_hash方法加密存储(使用 SHA-256 算法,加盐处理);
    • 基于角色的访问控制(RBAC):普通用户、高校用户、管理员拥有不同操作权限,例如管理员可删除任意内容,而普通用户仅能管理自己的评论。
  2. 数据安全

    • 敏感数据(如用户手机号、身份证号)在数据库中加密存储,解密密钥通过环境变量管理;
    • 数据库文件设置访问权限,仅 Web 服务器进程可读写,防止未授权访问;
    • 定期自动备份数据库(每日凌晨 3 点),备份文件存储在独立目录并加密。
  3. 防护措施

    • 防 SQL 注入:通过 SQLAlchemy ORM 的参数化查询,避免直接拼接 SQL 语句;
    • 防 XSS 攻击:使用 Jinja2 模板自动转义 HTML 特殊字符,对用户输入的富文本内容进行过滤;
    • 防 CSRF 攻击:通过 Flask-WTF 的 CSRF 令牌验证,确保表单提交来自合法页面;
    • 限流措施:对登录、注册等接口设置频率限制(如 1 分钟内最多 5 次请求),防止暴力破解。

四、开发环境搭建

(一)本地开发环境搭建

  1. Python 3.10.6 安装

    • 从 Python 官网(Python Release Python 3.10.6 | Python.org)下载对应操作系统的安装包;
    • 安装时勾选 "Add Python 3.10 to PATH",确保命令行可直接调用pythonpip
    • 验证安装:打开命令行,执行python --version,显示 "Python 3.10.6" 则安装成功。
  2. 虚拟环境创建与激活

    • 进入项目目录(如C:\projects\vietnam-study-in-china),执行以下命令创建虚拟环境:

      复制代码
      python -m venv vsic-venv

    进入项目目录最快的方法,在资源管理器上直接写上cmd(后面加空格),回车进入:

    创建虚拟环境:

    • 激活虚拟环境:
      • Windows(CMD):vsic-venv\Scripts\activate
      • Windows(PowerShell):.\vsic-venv\Scripts\Activate.ps1
      • macOS/Linux:source vsic-venv/bin/activate
    • 激活后命令行前缀显示(vsic-venv),表示当前处于虚拟环境中。
  3. 项目初始化与依赖安装

    • 创建requirements.txt文件,列出项目依赖:

      复制代码
      Flask==2.2.3
      Flask-SQLAlchemy==3.0.3
      Flask-Login==0.6.2
      Flask-WTF==1.1.1
      Jinja2==3.1.2
      Werkzeug==2.2.3
      sqlite3==2.6.0
      waitress==2.1.2
      pytest==7.3.1

    这一步,可以在本地开发完项目后,在通过命名pip freeze > requirements.txt,来自动导出项目所有依赖项,并保存到requirements.txt文件中。

    • 执行以下命令安装依赖: 当在服务器上部署项目时,可以通过requirements.txt文件安装项目相关的依赖项。

      复制代码
      pip install -r requirements.txt
  4. 开发工具配置

    • 安装 PyCharm 并打开项目,在 "File> Settings > Project: vietnam-study-in-china > Python Interpreter" 中选择虚拟环境的 Python 解释器(vsic-venv\Scripts\python.exe);

    • 配置 Git 仓库:初始化仓库(git init),创建.gitignore文件(忽略虚拟环境、日志文件、IDE 配置等):

      复制代码
      # 虚拟环境
      vsic-venv/
      # 日志
      logs/
      # 数据库文件
      *.db
      # PyCharm配置
      .idea/
      # 环境变量
      .env

(二)服务器环境搭建(Windows Server)

这个地方,要补充说明:

在本地开发有如上的项目,其中,app:项目代码文件夹;instance:sqlite数据库存放目录;vsic-venv:项目虚拟环境目录;run.py项目执行文件。

在其他服务器部署项目时,只要执行两步(创建和激活虚拟环境)即可运行项目,而不需要额外安装依赖项,但是此时不能新增或是修改已有的依赖项。

python -m venv vsic-venv

vsic-venv\Scripts\activate

  1. 操作系统配置

    • 阿里云 ECS 实例选择 Windows Server 2019 Datacenter 版本,配置至少 2 核 4GB 内存;可以看我的CSDN文章:阿里云ECS的windows server系统如何远程桌面连接-CSDN博客
    • 关闭不必要的系统服务(如 Windows Search),优化性能;
    • 开启远程桌面服务,便于远程管理(参考前文远程连接配置)。
  2. Python 安装与环境变量配置

    • 下载 Python 3.10.6 Windows 安装包,在服务器上安装,勾选 "Add Python to environment variables";
    • 验证安装:远程连接服务器,打开 CMD,执行python --version确认版本正确。
  3. Web 服务器配置(Waitress)

    • 由于 Windows 环境下不推荐使用 Flask 内置开发服务器(仅用于开发),采用 Waitress 作为生产环境 WSGI 服务器;
    • 安装 Waitress:pip install waitress(建议在服务器的虚拟环境中安装)。
  4. 数据库配置

    • SQLite 无需独立安装,随 Python 自带,只需确保项目目录有读写权限;
    • 为防止数据库文件损坏,设置定期备份任务(通过 Windows 任务计划程序实现)。
  5. 防火墙与端口配置

    • 开放 80 端口(HTTP)、443 端口(HTTPS)、5000 端口(Flask 应用);
    • 配置阿里云 ECS 安全组,允许公网访问上述端口(参考前文安全组配置步骤)。

五、数据库设计与实现

(一)数据库模型设计

  1. ER 图设计(核心实体关系)

    • 实体:用户(User)、院校(University)、专业(Major)、资讯(News)、咨询(Consultation)、收藏(Collection);
    • 关系:
      • 用户与咨询:一对多(一个用户可提交多个咨询);
      • 用户与收藏:一对多(一个用户可收藏多个院校);
      • 院校与专业:一对多(一个院校开设多个专业);
      • 院校与资讯:一对多(一个院校可发布多条资讯)。
  2. 核心数据表设计

    • users(用户表)

      字段名 类型 约束 说明
      id INTEGER PRIMARY KEY 自增主键
      username VARCHAR(50) UNIQUE, NOT NULL 用户名(唯一)
      password_hash VARCHAR(256) NOT NULL 加密存储的密码
      email VARCHAR(100) UNIQUE, NOT NULL 邮箱(唯一,用于登录)
      fullname VARCHAR(100) NOT NULL 姓名(越南语 / 中文)
      nationality VARCHAR(20) DEFAULT ' 越南' 国籍
      role VARCHAR(20) DEFAULT 'student' 角色(student/university/admin)
      university_id INTEGER FOREIGN KEY 关联院校 ID(仅高校用户)
      created_at DATETIME DEFAULT CURRENT_TIMESTAMP 注册时间
      status VARCHAR(10) DEFAULT 'active' 状态(active/disabled)
    • universities(院校表)

      字段名 类型 约束 说明
      id INTEGER PRIMARY KEY 自增主键
      name_cn VARCHAR(100) NOT NULL 院校中文名称
      name_vn VARCHAR(100) NOT NULL 院校越南语名称
      region VARCHAR(50) NOT NULL 所在地区(如北京)
      level VARCHAR(20) NOT NULL 层次(本科 / 硕士 / 语言学校)
      description_cn TEXT 中文简介
      description_vn TEXT 越南语简介
      website VARCHAR(200) 官方网站
      contact_email VARCHAR(100) 联系邮箱
      contact_phone VARCHAR(20) 联系电话
      is_verified BOOLEAN DEFAULT FALSE 是否认证(审核通过)
      created_at DATETIME DEFAULT CURRENT_TIMESTAMP 创建时间
    • majors(专业表)

      字段名 类型 约束 说明
      id INTEGER PRIMARY KEY 自增主键
      university_id INTEGER FOREIGN KEY 关联院校 ID
      name_cn VARCHAR(100) NOT NULL 专业中文名称
      name_vn VARCHAR(100) NOT NULL 专业越南语名称
      degree VARCHAR(20) NOT NULL 学位(学士 / 硕士 / 博士)
      duration INTEGER NOT NULL 学制(年)
      tuition DECIMAL(10,2) NOT NULL 学费(元 / 年)
      requirements TEXT 录取要求
    • news(资讯表)

      字段名 类型 约束 说明
      id INTEGER PRIMARY KEY 自增主键
      title_cn VARCHAR(200) NOT NULL 中文标题
      title_vn VARCHAR(200) NOT NULL 越南语标题
      content_cn TEXT NOT NULL 中文内容
      content_vn TEXT NOT NULL 越南语内容
      category VARCHAR(50) NOT NULL 类别(政策 / 院校动态 / 攻略)
      university_id INTEGER FOREIGN KEY 关联院校 ID(可选)
      author_id INTEGER FOREIGN KEY 作者 ID(管理员 / 高校用户)
      created_at DATETIME DEFAULT CURRENT_TIMESTAMP 发布时间
      is_published BOOLEAN DEFAULT FALSE 是否发布
    • consultations(咨询表)

      字段名 类型 约束 说明
      id INTEGER PRIMARY KEY 自增主键
      user_id INTEGER FOREIGN KEY 提问用户 ID
      title VARCHAR(200) NOT NULL 咨询标题
      content TEXT NOT NULL 咨询内容
      language VARCHAR(10) DEFAULT 'vn' 语言(vn/zh)
      status VARCHAR(20) DEFAULT 'pending' 状态(pending/answered/closed)
      reply_content TEXT 回复内容
      reply_user_id INTEGER FOREIGN KEY 回复用户 ID(管理员 / 高校)
      created_at DATETIME DEFAULT CURRENT_TIMESTAMP 提问时间
      replied_at DATETIME 回复时间
    • collections(收藏表)

      字段名 类型 约束 说明
      id INTEGER PRIMARY KEY 自增主键
      user_id INTEGER FOREIGN KEY 关联用户 ID
      university_id INTEGER FOREIGN KEY 关联院校 ID
      created_at DATETIME DEFAULT CURRENT_TIMESTAMP 收藏时间
      UNIQUE(user_id, university_id) 防止重复收藏

(二)数据库实现(SQLAlchemy ORM)

  1. 数据库连接配置

    在 Flask 应用初始化文件(如app/__init__.py)中配置数据库连接:

    复制代码
    from flask import Flask
    from flask_sqlalchemy import SQLAlchemy
    import os
    
    # 初始化Flask应用
    app = Flask(__name__, instance_relative_config=True)
    
    # 配置数据库路径(项目实例目录下的vsic_db.sqlite)
    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(app.instance_path, 'vsic_db.sqlite')
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False  # 禁用修改跟踪,提升性能
    
    # 确保实例目录存在
    try:
        os.makedirs(app.instance_path)
    except OSError:
        pass
    
    # 初始化SQLAlchemy
    db = SQLAlchemy(app)
  2. 模型类定义(app/models.py

    复制代码
    from datetime import datetime
    from flask_login import UserMixin
    from werkzeug.security import generate_password_hash, check_password_hash
    from app import db, login_manager
    
    class User(UserMixin, db.Model):
        __tablename__ = 'users'
    
        id = db.Column(db.Integer, primary_key=True)
        username = db.Column(db.String(50), unique=True, nullable=False)
        password_hash = db.Column(db.String(256), nullable=False)
        email = db.Column(db.String(100), unique=True, nullable=False)
        fullname = db.Column(db.String(100), nullable=False)
        nationality = db.Column(db.String(20), default='越南')
        role = db.Column(db.String(20), default='student')  # student/university/admin
        university_id = db.Column(db.Integer, db.ForeignKey('universities.id'), nullable=True)
        created_at = db.Column(db.DateTime, default=datetime.utcnow)
        status = db.Column(db.String(10), default='active')
    
        # 关系:用户发布的咨询
        consultations = db.relationship('Consultation', backref='user', lazy='dynamic')
        # 关系:用户的收藏
        collections = db.relationship('Collection', backref='user', lazy='dynamic')
    
        def set_password(self, password):
            self.password_hash = generate_password_hash(password)
    
        def check_password(self, password):
            return check_password_hash(self.password_hash, password)
    
    # 其他模型类(University、Major、News、Consultation、Collection)按数据表结构定义...
    
    # 登录管理器回调函数,用于加载用户
    @login_manager.user_loader
    def load_user(user_id):
        return User.query.get(int(user_id))
  3. 数据库初始化与迁移

    • 创建数据库表:在app/__init__.py中添加创建表的代码(仅首次执行):

      复制代码
      with app.app_context():
          db.create_all()  # 创建所有模型对应的表
    • 使用 Flask-Migrate 管理数据库迁移(适用于后期 schema 变更):

      复制代码
      # 安装Flask-Migrate
      pip install flask-migrate
      
      # 初始化迁移环境
      flask db init
      
      # 创建迁移脚本
      flask db migrate -m "Initial migration"
      
      # 应用迁移(创建表)
      flask db upgrade

六、前端架构设计与实现

(一)前端目录结构

复制代码
vietnam-study-in-china/
├── app/
│   ├── static/                # 静态资源
│   │   ├── css/               # 样式表
│   │   │   ├── base.css       # 基础样式
│   │   │   ├── home.css       # 首页样式
│   │   │   ├── university.css # 院校页面样式
│   │   │   └── admin.css      # 后台样式
│   │   ├── js/                # JavaScript脚本
│   │   │   ├── base.js        # 基础脚本(如语言切换)
│   │   │   ├── search.js      # 搜索功能脚本
│   │   │   └── form.js        # 表单验证脚本
│   │   ├── images/            # 图片资源
│   │   │   ├── logo.png       # 网站LOGO
│   │   │   ├── universities/  # 院校图片
│   │   │   └── banners/       # 轮播图图片
│   │   └── fonts/             # 字体文件(含越南语字体)
│   └── templates/             # 模板文件
│       ├── base/              # 基础模板
│       │   ├── base.html      # 主模板(包含导航栏、页脚)
│       │   ├── header.html    # 页头(导航栏)
│       │   └── footer.html    # 页脚
│       ├── home/              # 首页模板
│       │   └── index.html     # 首页
│       ├── university/        # 院校模块模板
│       │   ├── list.html      # 院校列表页
│       │   └── detail.html    # 院校详情页
│       ├── news/              # 资讯模块模板
│       │   ├── list.html      # 资讯列表页
│       │   └── detail.html    # 资讯详情页
│       ├── user/              # 用户模块模板
│       │   ├── login.html     # 登录页
│       │   ├── register.html  # 注册页
│       │   └── profile.html   # 个人中心
│       ├── consultation/      # 咨询模块模板
│       │   ├── create.html    # 提交咨询页
│       │   └── list.html      # 咨询记录页
│       └── admin/             # 后台模板
│           ├── index.html     # 后台首页
│           ├── user_manage.html # 用户管理页
│           └── content_manage.html # 内容管理页

(二)页面设计与实现规范

  1. 基础模板设计(base.html

    • 采用模板继承机制,所有页面继承自base.html,减少代码重复;

    • 包含语言切换按钮(中 / 越语),通过 JavaScript 切换页面文本;

    • 引入 Bootstrap 5 CSS 和 JS 文件,实现响应式布局:

      复制代码
      <!DOCTYPE html>
      <html lang="{{ current_language }}">
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>{% block title %}越南留学中国网{% endblock %}</title>
          <!-- 引入Bootstrap -->
          <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet">
          <!-- 引入自定义CSS -->
          <link rel="stylesheet" href="{{ url_for('static', filename='css/base.css') }}">
          {% block extra_css %}{% endblock %}
      </head>
      <body>
          <!-- 页头 -->
          {% include 'base/header.html' %}
      
          <!-- 主内容区 -->
          <main class="container py-4">
              {% block content %}{% endblock %}
          </main>
      
          <!-- 页脚 -->
          {% include 'base/footer.html' %}
      
          <!-- 引入jQuery和Bootstrap JS -->
          <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
          <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
          <!-- 引入语言切换脚本 -->
          <script src="{{ url_for('static', filename='js/base.js') }}"></script>
          {% block extra_js %}{% endblock %}
      </body>
      </html>
  2. 响应式设计规范

    • 使用 Bootstrap 的网格系统(containerrowcol-*)实现多设备适配;
    • 移动端优先:默认样式适配手机,通过@media (min-width: 768px)等媒体查询适配平板和桌面端;
    • 导航栏在移动端自动折叠为汉堡菜单,通过 Bootstrap 的 Navbar 组件实现。
  3. 中越双语实现

    • 在静态文本中使用数据属性存储双语内容,例如:

      复制代码
      <h1 data-zh="欢迎来到越南留学中国网" data-vn="Chào mừng đến với trang web Du học Trung Quốc từ Việt Nam"></h1>
    • JavaScript 脚本根据用户选择的语言切换显示内容:

      复制代码
      // base.js
      $(document).ready(function() {
          // 默认语言为越南语
          let currentLang = 'vn';
          
          // 语言切换按钮点击事件
          $('#lang-switch').click(function() {
              currentLang = currentLang === 'zh' ? 'vn' : 'zh';
              switchLanguage(currentLang);
          });
          
          // 切换语言函数
          function switchLanguage(lang) {
              $('[data-zh][data-vn]').each(function() {
                  $(this).text($(this).data(lang));
              });
              // 更新页面lang属性
              $('html').attr('lang', lang);
              // 存储用户语言偏好到localStorage
              localStorage.setItem('preferredLanguage', lang);
          }
          
          // 加载用户上次选择的语言
          const savedLang = localStorage.getItem('preferredLanguage');
          if (savedLang) {
              switchLanguage(savedLang);
          }
      });

(三)核心页面设计说明

  1. 首页(home/index.html

    • 顶部轮播图:展示 3-5 张热门院校或留学政策宣传图,自动切换;
    • 快捷入口区:包含 "院校查询""申请指南""最新资讯""在线咨询" 四个图标按钮,链接至对应页面;
    • 热门院校展示:以卡片形式展示 6 所认证院校,包含 LOGO、名称、地区、简介,点击进入详情页;
    • 留学资讯推荐:展示 3 条最新资讯,包含标题、发布时间、摘要;
    • 数据统计区:使用 Chart.js 绘制越南在华留学生人数趋势图、热门专业分布饼图。
  2. 院校列表页(university/list.html

    • 筛选区:包含地区下拉框(北京、上海、广东等)、层次复选框(本科、硕士、语言学校)、专业搜索框,支持组合筛选;
    • 排序功能:支持按 "关注度""学费(从低到高)""成立时间" 排序;
    • 院校列表:以网格布局展示院校卡片,包含 LOGO、名称(中越双语)、地区、层次、学费范围、认证状态,卡片底部有 "查看详情" 和 "收藏" 按钮;
    • 分页控件:底部显示分页导航,支持跳转到指定页码,每页显示 12 条记录。
  3. 院校详情页(university/detail.html

    • 院校头部:展示院校 LOGO、名称(中越双语)、地区、层次、认证状态,右上角有 "收藏" 按钮(已登录用户可见);
    • 标签页导航:包含 "院校简介""专业设置""招生要求""联系方式" 四个标签页,点击切换内容;
    • 专业列表:在 "专业设置" 标签页中,以表格形式展示专业名称、学位、学制、学费、录取要求;
    • 相关资讯:底部展示该院校发布的最新资讯,最多 5 条;
    • 咨询入口:提供 "向该校咨询" 按钮,点击跳转到咨询提交页(自动填充院校信息)。
  4. 用户中心(user/profile.html

    • 个人信息区:展示用户名、邮箱、姓名、国籍等基本信息,提供 "编辑" 按钮;
    • 收藏管理:展示用户收藏的院校列表,支持取消收藏;
    • 咨询记录:展示用户提交的咨询列表,包含标题、状态(未回复 / 已回复)、提交时间,点击可查看详情及回复;
    • 消息通知:显示系统消息(如收藏的院校有新资讯),未读消息标红提示。
  5. 后台管理首页(admin/index.html

    • 数据概览:展示网站总访问量、注册用户数、院校数量、资讯数量、咨询数量的统计卡片;
    • 趋势图表:展示近 7 天用户注册量、资讯发布量、咨询提交量的折线图;
    • 待办事项:显示待审核的院校、待回复的咨询、待发布的资讯数量,点击可跳转到对应管理页;
    • 操作快捷入口:提供 "发布资讯""审核院校""回复咨询" 的快速按钮。

七、后端核心功能开发

(一)应用初始化与蓝图配置

  1. 应用入口文件(run.py

    复制代码
    from app import create_app
    
    # 创建Flask应用实例
    app = create_app()
    
    if __name__ == '__main__':
        # 开发环境使用内置服务器
        app.run(debug=True)
        # 生产环境使用Waitress(通过命令行启动)
        #  waitress-serve --host 0.0.0.0 --port 5000 run:app
  2. 应用工厂函数(app/__init__.py

    复制代码
    from flask import Flask
    from flask_sqlalchemy import SQLAlchemy
    from flask_login import LoginManager
    from flask_wtf.csrf import CSRFProtect
    import os
    
    # 初始化扩展
    db = SQLAlchemy()
    login_manager = LoginManager()
    login_manager.login_view = 'user.login'  # 登录页面路由
    csrf = CSRFProtect()
    
    def create_app(test_config=None):
        # 创建并配置应用
        app = Flask(__name__, instance_relative_config=True)
        app.config.from_mapping(
            SECRET_KEY=os.environ.get('SECRET_KEY') or 'dev-key-for-development-only',
            SQLALCHEMY_DATABASE_URI='sqlite:///' + os.path.join(app.instance_path, 'vsic_db.sqlite'),
            SQLALCHEMY_TRACK_MODIFICATIONS=False,
        )
    
        if test_config is None:
            # 加载实例配置(如果存在)
            app.config.from_pyfile('config.py', silent=True)
        else:
            # 加载测试配置
            app.config.from_mapping(test_config)
    
        # 确保实例目录存在
        try:
            os.makedirs(app.instance_path)
        except OSError:
            pass
    
        # 初始化扩展
        db.init_app(app)
        login_manager.init_app(app)
        csrf.init_app(app)
    
        # 注册蓝图
        from app.blueprints import home, user, university, news, consultation, admin
        app.register_blueprint(home.bp)
        app.register_blueprint(user.bp)
        app.register_blueprint(university.bp)
        app.register_blueprint(news.bp)
        app.register_blueprint(consultation.bp)
        app.register_blueprint(admin.bp)
    
        # 设置首页路由
        app.add_url_rule('/', endpoint='index')
    
        return app
  3. 蓝图定义(以用户模块为例,app/blueprints/user.py

    复制代码
    from flask import Blueprint, render_template, redirect, url_for, request, flash
    from flask_login import login_user, logout_user, login_required, current_user
    from app.models import User
    from app import db
    from app.forms import LoginForm, RegistrationForm
    
    bp = Blueprint('user', __name__, url_prefix='/user')
    
    @bp.route('/login', methods=['GET', 'POST'])
    def login():
        if current_user.is_authenticated:
            return redirect(url_for('home.index'))
        form = LoginForm()
        if form.validate_on_submit():
            user = User.query.filter_by(email=form.email.data).first()
            if user is None or not user.check_password(form.password.data):
                flash('邮箱或密码错误')
                return redirect(url_for('user.login'))
            if user.status != 'active':
                flash('账号已被禁用,请联系管理员')
                return redirect(url_for('user.login'))
            login_user(user, remember=form.remember_me.data)
            next_page = request.args.get('next')
            return redirect(next_page or url_for('home.index'))
        return render_template('user/login.html', form=form)
    
    @bp.route('/logout')
    @login_required
    def logout():
        logout_user()
        return redirect(url_for('home.index'))
    
    @bp.route('/register', methods=['GET', 'POST'])
    def register():
        if current_user.is_authenticated:
            return redirect(url_for('home.index'))
        form = RegistrationForm()
        if form.validate_on_submit():
            user = User(
                username=form.username.data,
                email=form.email.data,
                fullname=form.fullname.data,
                nationality=form.nationality.data,
                role='student'
            )
            user.set_password(form.password.data)
            db.session.add(user)
            db.session.commit()
            flash('注册成功,请登录')
            return redirect(url_for('user.login'))
        return render_template('user/register.html', form=form)
    
    @bp.route('/profile')
    @login_required
    def profile():
        return render_template('user/profile.html', user=current_user)

(二)核心功能模块开发

  1. 用户模块

    • 注册与登录:使用 Flask-WTF 处理表单验证,Flask-Login 管理用户会话;
    • 权限控制 :通过@login_required装饰器限制登录后访问,通过角色判断(current_user.role)限制管理员功能;
    • 个人信息管理:支持用户修改姓名、邮箱、密码(需验证旧密码)。
  2. 院校模块

    • 院校列表与筛选 :接收前端传递的地区、专业等筛选参数,构建 SQL 查询条件:

      复制代码
      @bp.route('/list')
      def list():
          # 获取筛选参数
          region = request.args.get('region', '')
          level = request.args.get('level', '')
          major = request.args.get('major', '')
          
          # 构建查询
          query = University.query.filter_by(is_verified=True)
          if region:
              query = query.filter(University.region == region)
          if level:
              query = query.filter(University.level == level)
          if major:
              # 关联查询包含该专业的院校
              query = query.join(Major).filter(Major.name_cn.like(f'%{major}%') | Major.name_vn.like(f'%{major}%'))
          
          # 分页(每页12条)
          page = request.args.get('page', 1, type=int)
          pagination = query.paginate(page=page, per_page=12)
          universities = pagination.items
          
          return render_template('university/list.html', universities=universities, pagination=pagination)
    • 院校收藏 :登录用户可收藏院校,通过Collection模型记录关联关系,支持取消收藏。

  3. 资讯模块

    • 资讯发布与管理:管理员和高校用户可发布资讯(需填写中越双语内容),支持编辑、删除、草稿保存;
    • 资讯分类与搜索:按类别(政策 / 院校动态 / 攻略)筛选,支持关键词搜索(同时匹配标题和内容)。
  4. 咨询模块

    • 咨询提交与回复:用户可提交中 / 越语咨询,管理员或对应院校用户可回复,回复后通过邮件通知用户;
    • 咨询状态跟踪:显示咨询的状态(未回复 / 已回复 / 已关闭),用户可查看回复内容。
  5. 后台管理模块

    • 用户管理:管理员可查看所有用户列表,按角色筛选,禁用违规用户;
    • 内容审核:审核院校认证申请(验证院校资质)、资讯发布申请;
    • 数据统计:通过 SQL 查询统计用户增长、访问量、热门院校等数据,生成报表。

(三)表单处理与验证

  1. 表单定义(app/forms.py

    复制代码
    from flask_wtf import FlaskForm
    from wtforms import StringField, PasswordField, BooleanField, SubmitField, TextAreaField, SelectField
    from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError
    from app.models import User
    
    class LoginForm(FlaskForm):
        email = StringField('邮箱', validators=[DataRequired(), Email()])
        password = PasswordField('密码', validators=[DataRequired()])
        remember_me = BooleanField('记住我')
        submit = SubmitField('登录')
    
    class RegistrationForm(FlaskForm):
        username = StringField('用户名', validators=[DataRequired(), Length(min=4, max=50)])
        email = StringField('邮箱', validators=[DataRequired(), Email()])
        fullname = StringField('姓名', validators=[DataRequired(), Length(min=2, max=100)])
        nationality = StringField('国籍', validators=[DataRequired()], default='越南')
        password = PasswordField('密码', validators=[DataRequired(), Length(min=6)])
        password2 = PasswordField('确认密码', validators=[DataRequired(), EqualTo('password')])
        submit = SubmitField('注册')
    
        def validate_email(self, email):
            user = User.query.filter_by(email=email.data).first()
            if user is not None:
                raise ValidationError('该邮箱已被注册,请使用其他邮箱')
    
        def validate_username(self, username):
            user = User.query.filter_by(username=username.data).first()
            if user is not None:
                raise ValidationError('该用户名已被使用,请选择其他用户名')
    
    # 其他表单(如咨询表单、资讯发布表单)按类似方式定义...
  2. 表单渲染与提交

    在模板中渲染表单,并处理提交数据:

    复制代码
    <!-- user/login.html -->
    {% extends 'base/base.html' %}
    
    {% block title %}登录 - 越南留学中国网{% endblock %}
    
    {% block content %}
    <div class="row justify-content-center">
        <div class="col-md-6">
            <h2 data-zh="用户登录" data-vn="Đăng nhập người dùng"></h2>
            <form method="post">
                {{ form.hidden_tag() }}  <!-- CSRF令牌 -->
                
                <div class="mb-3">
                    {{ form.email.label(data-zh="邮箱", data-vn="Email") }}
                    {{ form.email(class="form-control") }}
                    {% for error in form.email.errors %}
                    <span class="text-danger">{{ error }}</span>
                    {% endfor %}
                </div>
                
                <div class="mb-3">
                    {{ form.password.label(data-zh="密码", data-vn="Mật khẩu") }}
                    {{ form.password(class="form-control") }}
                    {% for error in form.password.errors %}
                    <span class="text-danger">{{ error }}</span>
                    {% endfor %}
                </div>
                
                <div class="mb-3 form-check">
                    {{ form.remember_me(class="form-check-input") }}
                    {{ form.remember_me.label(class="form-check-label", data-zh="记住我", data-vn="Ghi nhớ tôi") }}
                </div>
                
                {{ form.submit(class="btn btn-primary", data-zh="登录", data-vn="Đăng nhập") }}
            </form>
            <p class="mt-3">
                <a href="{{ url_for('user.register') }}" data-zh="还没有账号?注册" data-vn="Chưa có tài khoản? Đăng ký"></a>
            </p>
        </div>
    </div>
    {% endblock %}

八、系统集成与测试

(一)单元测试

  1. 测试环境配置

    创建tests目录,编写测试配置文件tests/conftest.py

    复制代码
    import pytest
    from app import create_app, db
    from app.models import User, University
    
    @pytest.fixture
    def app():
        # 使用内存数据库进行测试
        app = create_app({
            'TESTING': True,
            'SQLALCHEMY_DATABASE_URI': 'sqlite:///:memory:'
        })
    
        # 创建测试数据
        with app.app_context():
            db.create_all()
            # 添加测试用户
            user = User(username='testuser', email='test@example.com', fullname='测试用户')
            user.set_password('testpassword')
            db.session.add(user)
            db.session.commit()
    
        yield app
    
    @pytest.fixture
    def client(app):
        return app.test_client()
    
    @pytest.fixture
    def runner(app):
        return app.test_cli_runner()
  2. 核心功能测试示例

    • 用户登录测试(tests/test_user.py):

    def test_login(client):

    访问登录页

    response = client.get('/user/login')

    assert 200 == response.status_code

    提交正确的登录信息

    response = client.post (

    '/user/login',

    data={'email': 'test@example.com', 'password': 'testpassword'},

    follow_redirects=True

    )

    assert 200 == response.status_code

    assert b' 测试用户 ' in response.data # 登录后显示用户名

    提交错误的密码

    response = client.post (

    '/user/login',

    data={'email': 'test@example.com', 'password': 'wrongpassword'},

    follow_redirects=True

    )

    assert b' 邮箱或密码错误 ' in response.data

    复制代码
    - 院校查询测试(`tests/test_university.py`):  
      ```python
    def test_university_list(client, app):
        # 添加测试院校
        with app.app_context():
            from app.models import University
            uni = University(
                name_cn='测试大学',
                name_vn='Trường Đại học kiểm tra',
                region='北京',
                level='本科',
                is_verified=True
            )
            db.session.add(uni)
            db.session.commit()
        
        # 访问院校列表页
        response = client.get('/university/list')
        assert 200 == response.status_code
        assert b'测试大学' in response.data
        
        # 按地区筛选
        response = client.get('/university/list?region=北京')
        assert b'测试大学' in response.data
        
        # 按不存在的地区筛选
        response = client.get('/university/list?region=上海')
        assert b'测试大学' not in response.data

(二)集成测试

  1. 流程测试

    测试完整业务流程,如 "用户注册→登录→收藏院校→查看收藏":

    复制代码
    def test_user_collection_flow(client, app):
        # 注册新用户
        client.post(
            '/user/register',
            data={
                'username': 'newuser',
                'email': 'new@example.com',
                'fullname': '新用户',
                'nationality': '越南',
                'password': 'newpassword',
                'password2': 'newpassword'
            },
            follow_redirects=True
        )
        
        # 登录新用户
        client.post(
            '/user/login',
            data={'email': 'new@example.com', 'password': 'newpassword'},
            follow_redirects=True
        )
        
        # 添加测试院校
        with app.app_context():
            from app.models import University
            uni = University(
                name_cn='北京大学',
                name_vn='Trường Đại học Bắc Kinh',
                region='北京',
                level='本科',
                is_verified=True
            )
            db.session.add(uni)
            db.session.commit()
            uni_id = uni.id
        
        # 收藏院校
        response = client.get(f'/university/collect/{uni_id}', follow_redirects=True)
        assert b'收藏成功' in response.data
        
        # 查看个人收藏
        response = client.get('/user/profile#collections')
        assert 200 == response.status_code
        assert b'北京大学' in response.data
  2. 接口测试

    使用 Postman 测试 API 接口,验证返回格式和数据正确性:

    • 测试GET /api/universities接口:检查返回的院校列表格式是否符合规范,分页参数是否生效;
    • 测试POST /api/users/login接口:验证正确的账号密码返回 200 状态码和用户信息,错误信息返回 401 状态码。

(三)性能与兼容性测试

  1. 性能测试

    • 使用locust工具进行负载测试:模拟 100 个并发用户访问首页、院校列表页,测试响应时间(目标≤3 秒);
    • 数据库查询优化:对热门查询(如院校列表)添加索引,使用EXPLAIN ANALYZE分析查询性能,确保查询时间≤100ms。
  2. 兼容性测试

    • 浏览器兼容性:在 Chrome、Firefox、Safari、Edge 等主流浏览器中测试页面显示和功能,确保一致的用户体验;
    • 设备兼容性:使用浏览器开发者工具模拟手机(iPhone、Android)、平板设备,测试响应式布局是否正确。

九、部署与上线

(一)服务器配置

  1. 阿里云 ECS 实例配置

    • 实例规格:2 核 4GB 内存,40GB SSD 云盘;
    • 操作系统:Windows Server 2019 Datacenter;
    • 网络:分配公网 IP,绑定弹性公网 IP(EIP),确保 IP 固定;
    • 安全组:开放 80 端口(HTTP)、443 端口(HTTPS)、5000 端口(Flask 应用)。
  2. 环境部署步骤

    • 远程连接服务器(使用远程桌面);

    • 安装 Python 3.10.6,配置环境变量;

    • 创建项目目录:C:\website\vietnam-study-in-china

    • 上传项目文件至服务器(通过 FTP 或远程桌面文件传输);

    • 创建并激活虚拟环境:

      复制代码
      cd C:\website\vietnam-study-in-china
      python -m venv vsic-venv
      vsic-venv\Scripts\activate
    • 安装依赖:pip install -r requirements.txt

    • 初始化数据库:

      复制代码
      set FLASK_APP=run.py
      flask db upgrade

(二)应用部署

  1. 使用 Waitress 启动应用

    创建启动脚本start_app.bat

    复制代码
    @echo off
    cd /d C:\website\vietnam-study-in-china
    vsic-venv\Scripts\activate
    waitress-serve --host 0.0.0.0 --port 5000 run:app

    双击运行脚本,验证应用是否启动(访问http://127.0.0.1:5000)。

  2. 配置 Windows 服务(实现开机自启)

    • 使用nssm工具将应用注册为 Windows 服务:

      复制代码
      nssm install VietnamStudyInChina
    • 在弹出的窗口中设置:

      • Path:C:\website\vietnam-study-in-china\vsic-venv\Scripts\waitress-serve.exe
      • Arguments:--host 0.0.0.0 --port 5000 run:app
      • Working Directory:C:\website\vietnam-study-in-china
    • 启动服务:nssm start VietnamStudyInChina

  3. 配置反向代理(IIS)

    • 安装 IIS 及 URL 重写模块;

    • 创建网站,绑定域名(如www.vietnam-study-in-china.com);

    • 配置 URL 重写,将请求转发至 5000 端口:

      复制代码
      <!-- web.config -->
      <?xml version="1.0" encoding="UTF-8"?>
      <configuration>
        <system.webServer>
          <rewrite>
            <rules>
              <rule name="ReverseProxy" stopProcessing="true">
                <match url="(.*)" />
                <action type="Rewrite" url="http://localhost:5000/{R:1}" />
              </rule>
            </rules>
          </rewrite>
        </system.webServer>
      </configuration>

(三)域名绑定与 SSL 配置

  1. 域名解析

    • 在域名注册商控制台添加 A 记录,将域名指向服务器公网 IP;
    • 等待 DNS 生效(通常 10-30 分钟),使用nslookup验证解析是否正确。
  2. SSL 证书配置(HTTPS)

    • 在阿里云 SSL 证书服务申请免费 SSL 证书(Let's Encrypt);

    • 下载证书文件(包含.pem.key文件),上传至服务器;

    • 在 IIS 中导入证书:服务器证书→导入→选择证书文件;

    • 网站绑定添加 HTTPS 类型,选择导入的证书,端口 443;

    • 配置 URL 重写,强制跳转 HTTPS:

      复制代码
      <rule name="HTTP to HTTPS" stopProcessing="true">
        <match url="(.*)" />
        <conditions>
          <add input="{HTTPS}" pattern="off" />
        </conditions>
        <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
      </rule>

(四)上线前检查清单

  1. 功能检查

    • 验证所有核心功能(注册、登录、院校查询、资讯浏览、咨询提交)是否正常;
    • 检查中越双语切换是否生效,文本是否正确显示;
    • 测试用户权限控制(如普通用户无法访问后台)。
  2. 性能检查

    • 使用浏览器开发者工具检查页面加载时间,确保≤3 秒;
    • 测试数据库查询性能,热门页面查询时间≤100ms;
    • 验证并发访问(使用工具模拟 100 用户)时系统是否稳定。
  3. 安全检查

    • 确认密码加密存储,敏感数据传输使用 HTTPS;
    • 测试防 SQL 注入(在搜索框输入特殊字符如' OR 1=1 --);
    • 检查 CSRF 令牌是否生效(禁用 JavaScript 后提交表单)。
  4. 数据备份

    • 手动备份数据库文件(vsic_db.sqlite)至独立存储;
    • 验证备份文件可正常恢复(在测试环境恢复并检查数据完整性)。

十、项目维护与迭代

(一)日常维护

  1. 服务器监控

    • 使用阿里云云监控:监控 CPU 使用率、内存占用、带宽流量,设置阈值告警(如 CPU>80% 时短信通知);
    • 应用日志监控:配置 Flask 日志输出至文件(logs/app.log),定期查看错误日志,及时修复 BUG。
  2. 数据备份

    • 自动备份:通过 Windows 任务计划程序,每日凌晨 3 点执行数据库备份脚本:

      复制代码
      @echo off
      set BACKUP_DIR=C:\backup\vsic
      set TIMESTAMP=%date:~0,4%%date:~5,2%%date:~8,2%%time:~0,2%%time:~3,2%%time:~6,2%
      copy C:\website\vietnam-study-in-china\instance\vsic_db.sqlite %BACKUP_DIR%\vsic_db_%TIMESTAMP%.sqlite
    • 备份保留策略:保留最近 30 天的备份文件,自动删除过期文件。

  3. 系统更新

    • 定期更新服务器操作系统补丁(通过 Windows Update);
    • 定期更新项目依赖包(pip list --outdated查看更新,pip upgrade更新),更新前需在测试环境验证兼容性。

(二)问题修复与迭代

  1. BUG 修复流程

    • 收集 BUG:通过用户反馈、日志监控发现问题;
    • 优先级分类:Critical(如登录失败)→ High(如页面显示异常)→ Medium(如排版问题)→ Low(如错别字);
    • 修复与验证:在开发环境修复,提交测试环境验证,通过后部署至生产环境。
  2. 功能迭代计划

    • 短期迭代(1-2 个月):
      • 增加留学费用计算器功能;
      • 优化搜索算法,支持越南语分词搜索;
      • 接入微信支付,支持在线缴纳申请费。
    • 中期迭代(3-6 个月):
      • 开发移动 APP(基于 Flutter),实现与网站数据同步;
      • 增加视频面试功能,连接越南学生与中国高校;
      • 接入 AI 智能咨询机器人,自动回复常见问题。
    • 长期迭代(1 年以上):
      • 扩展至其他东南亚国家(如老挝、柬埔寨);
      • 与中国教育部留学服务中心对接,实现学历认证查询。
  3. 性能优化

    • 数据库优化:对大表(如资讯表)进行分区,添加合适的索引,定期清理冗余数据;
    • 缓存优化:使用 Redis 缓存热门院校、资讯数据,减少数据库查询;
    • 前端优化:压缩静态资源(CSS/JS/ 图片),使用 CDN 加速静态资源分发。

十一、总结与展望

(一)项目总结

本项目 "vietnam-study-in-china" 基于 Python 3.10.6、Flask、SQLite 技术栈,构建了一个面向越南学生的赴华留学信息平台。通过需求分析、系统设计、开发实现、测试部署等阶段,完成了用户管理、院校展示、资讯发布、在线咨询等核心功能,并通过阿里云 ECS 部署上线,实现了域名绑定与 HTTPS 访问。

项目开发过程中,重点解决了以下问题:

  • 中越双语切换:通过前端数据属性与 JavaScript 实现页面文本动态切换;
  • 数据安全:采用密码加密存储、CSRF 防护、SQL 注入防护等措施;
  • 部署稳定性:使用 Waitress 作为生产服务器,配置 Windows 服务实现开机自启;
  • 用户体验:通过响应式设计适配多设备,优化页面加载速度。

(二)项目展望

随着中越教育交流的深入,越南留学中国网有望成为两国教育合作的重要桥梁。未来可从以下方面进一步发展:

  1. 拓展服务范围:除信息展示外,增加在线申请、签证代办、接机服务等增值服务;
  2. 深化技术应用:引入大数据分析用户行为,提供个性化院校推荐;
  3. 加强合作生态:与中国高校、越南中学建立合作,提供招生代理、生源输送服务;
  4. 国际化扩展:在越南设立本地化运营团队,提升服务响应速度与本地化程度。

通过持续迭代与优化,项目将为越南学生赴华留学提供更便捷、高效的服务,助力中越教育交流与合作迈向新高度。