ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于 FastAPI+Vue3 的项目

基于 FastAPI+Vue3 的项目 这是我的一个个人项目做这个项目的目的是解决生活的一些问题。不论是平时生活还在商业活动中合同是所有合作的基石但一份十几页的合同往往藏着普通人难以察觉的风险条款。一、这个项目到底解决什么问题我们在做一个项目的时候就应该想好这个项目要实现什么功能。是给谁用的是自用还是其他用户使用。根据这个我们就要考虑到安全性易用性使用体验。要明白1. 用户想要解决什么痛点不要只看功能看背后诉求2. 使用场景什么时候、在哪里使用3. 预期规模多少人同时使用数据量大概多少决定技术选型4. 成功标准怎么判断项目做完算合格减少后期需求反复变更不要上来罗列一堆功能先区分核心功能MVP 最小可行产品没有它项目就失去价值必须第一版实现次要功能锦上添花二期迭代开发我们现有的技术能不能实现如果实现不了能不能借助 AI 帮忙实现。做一个项目还有哪些需求我做这个项目就是为了解决生活中合同审查。合同审查的核心痛点集中在三个维度专业门槛高合同文本充斥法言法语非专业人士读不懂条款的真实含义对己方不利的条款往往被包装在专业表述中难以识别。审查效率低一份 十几页的合同人工逐字审查需要数小时且长时间阅读极易遗漏细节风险。成本门槛高聘请专业律师审查合同费用高昂小额合同、个人合同、初创企业的日常合同往往不值得付出高额律师成本。目标目标实现方式降低审查门槛上传合同 → AI 自动拆条款 → 标红风险点 → 一键下载标注版降低起草门槛选模板 → 填变量 → AI 自动补全文 → 一键送审降低比对门槛选两份合同 → AI 自动对比差异 → 红色高亮不同点保证工程专业性全栈可本地启动、可生产部署、可水平扩展二、完整技术栈这个项目的功能比较简单但也是一套工程规范完整、可直接落地的全栈应用。这个项目在做的时候就规范好了文件结构、API接口规划、模块化路由。项目采用前后端分离架构技术选型兼顾开发效率、运行性能与可扩展性完整技术栈如下这是项目结构ContractMirror/├── backend/ # FastAPI 后端│ ├── app/│ │ ├── core/ # 基础设施: config · database · security · exceptions · middleware│ │ ├── models/ # SQLAlchemy ORM 模型│ │ ├── repositories/ # 数据访问层(纯 CRUD,无业务)│ │ ├── services/ # 业务逻辑层(审查 · 起草 · 导出 · LLM · 解析 · SSE · 邮件)│ │ ├── routers/ # HTTP 路由(API 入口)│ │ ├── schemas/ # Pydantic 请求/响应模型│ │ └── __init__.py│ ├── sql/ # 数据库初始化 种子数据│ ├── tests/ # pytest 自动化测试│ ├── scripts/ # 调试脚本│ ├── logs/pipeline/ # 审查管线日志(每个 review 一个 .log)│ ├── uploads/ # 用户上传文件│ ├── main.py # FastAPI 入口│ └── pyproject.toml├── frontend/ # Vue 3 前端│ ├── src/│ │ ├── api/ # 后端 API 封装(axios 类型契约)│ │ ├── components/ # 通用组件(NavBar · ClauseCard · DraftForm ...)│ │ ├── views/ # 页面(Home · Draft · Result ...)│ │ ├── stores/ # Pinia 状态管理│ │ ├── router/ # Vue Router│ │ ├── composables/ # 组合式函数(倒计时等)│ │ ├── assets/ # 静态资源│ │ └── main.ts│ ├── vite.config.ts│ ├── tailwind.config.js│ └── package.json├── docs/ # 项目文档(API · 部署 · 隐私)├── docker-compose.yml # 一键拉起 MySQL├── integration_check.py # 端到端联调检查└── README.md # 本文件前端技术栈详解技术用途关键设计Vue 3 组合式 API视图层script setup语法糖Vite构建HMR 极速,无 webpack 启动延迟TypeScript类型安全严格模式,API 响应类型契约Pinia状态管理替代 Vuex,无 mutationsVue Router 4路由懒加载路由(() import())Element PlusUI 组件库ElMessage / ElForm / ElUploadTailwindCSS原子化样式自定义设计令牌AxiosHTTP拦截器统一加 token / 错误处理后端技术栈详解技术用途关键设计FastAPIWeb 框架async 原生、Pydantic 自动校验、OpenAPI 自动生成SQLAlchemy 2.x asyncORMAsyncSessionselect()mapped_columnPydantic 2数据验证BaseModelFieldmodel_validatorpython-joseJWTHS256passlib bcrypt密码哈希12 roundshttpx异步 HTTP调 DeepSeekpypdfPDF 解析 合并读 PDF 写 PDFpython-docxDOCX 生成段落/标题/落款reportlabPDF 渲染中文需注册 TTF 字体aiosmtplib异步 SMTPQQ 邮箱发验证码数据库设计users 认证用户├─ id (PK) · email (UK) · password_hash · created_at└─ client_ip (注册 IP,频控用)templates 合同模板(15 个内置)├─ id (PK) · category · title · description└─ content (JSON: {body, variables})drafts 起草的草稿├─ id (PK) · user_id (FK) · template_id (FK) · title└─ content · variables (JSON)review_tasks 审查任务├─ id (PK) · user_id (FK) · file_path · file_format└─ status (pending/running/completed/failed) · score · summaryreview_clauses 审查拆出的条款├─ id (PK) · review_id (FK) · clause_index · original_text└─ risk_level (high/medium/low) · comment · suggestion当然项目结构根据我们不断新增功能也是会不断更新的。三、如何提高AI效率添加规则文件规则文件的作用在提问前就加载到系统上下文中定义规则、约束 AI让它更懂项目还能省 Token。主流 Coding agent 都支持Claude Code、Codex、CodeBuddy、Trae、Qwen生成方式有两种生成方法一init 命令所有编程类 agent 都支持 init 命令Claude Code、Codex、CodeBuddy 等执行后 AI 会扫描项目核心文件了解业务背景和技术栈生成一个粗略版本Claude Code 生成的内容包含项目描述、常见命令、核心文件生成方法二对话形式 .md 说明用对话形式把一段提示词发给 AI即可得到规则文件.md 是什么Markdown 文件一种文本文件用特殊符号标识标题、加粗等样式很适合 AI 阅读。帮我在这个项目目录下生成一份规则文件按下面这个要求。模板------## 项目概述这个项目是干嘛的业务场景解决什么问题## 技术栈项目用了什么编程语言技术框架....对应的版本是什么....## 常用命令安装依赖用什么怎么验证、生产构建怎么跑。## 代码规范1、单个业务代码文件不能超过300行职责分离。2、不要随便引入新的框架。3、复用现有组件工具类...## 工作原则- 编码前先思考不懂的先向我提问不要瞎编- 代码简洁------四、关键代码片段这是项目核心的审查流程async def run_pipeline(self, review_id: str, file_path: str, file_format: str) - None: 审查管线 (异步执行) - 由 router 通过 asyncio.create_task 调度 - background task 抛错不会回到 HTTP,故最外层 try/except 落盘到 logs/pipeline/{id}.log from app.core.database import AsyncSessionLocal _write_pipeline_log(review_id, f[pipeline] STARTED format{file_format} path{file_path}) print(f[pipeline] STARTED review_id{review_id} format{file_format}, flushTrue) logger.info([pipeline] started review_id%s format%s, review_id, file_format) try: await sse_service.push_event(review_id, {stage: parsing, message: 正在解析文件...}) async with AsyncSessionLocal() as db: try: _write_pipeline_log(review_id, [pipeline] about to get_by_id) task await review_task_repo.get_by_id(db, review_id) _write_pipeline_log(review_id, f[pipeline] get_by_id OK: {task.id if task else None}) if not task: _write_pipeline_log(review_id, [pipeline] task not found, return) return task.status running await db.commit() _write_pipeline_log(review_id, [pipeline] statusrunning committed) # 阶段 1: 解析原始文件 # 这段代码的作用: 将用户上传的原始文件(如 PDF/Word/TXT 等)提取并转换为纯文本内容。 text, page_count, preview await parser_service.parse_file(file_path, file_format) # 将解析得到的页数更新到当前审查任务(task)的 ORM 对象中 # 阶段 2: 分割合同条款 # 这段代码的作用: 将一整篇长文本按照合同条款的层级结构(如第一条、1.、(一)等)拆分成独立的条款列表。 await sse_service.push_event(review_id, {stage: splitting, message: 正在识别条款...}) # 调用解析服务的分割方法将纯文本切分为条款列表每个元素通常是包含 index, title, text 等信息的字典 clauses parser_service.split_clauses(text) # 记录拆分出的条款总数存入 task 对象。这个总数将用于后续并发审查时的进度计算如已完成 3/10 条和最终的结果统计 task.total_clauses len(clauses) # 提交数据库事务持久化条款总数 await db.commit() await sse_service.push_event(review_id, {stage: searching, message: 正在检索相关法条...}) # 写入调试信息(用 debug 版 split,不含 text 避免膨胀) await review_debug_repo.create( db, review_idreview_id, file_previewpreview, split_strategyregex: 第X条 / 数字. / (一), clause_splitparser_service.split_clauses_for_debug(text), model_namesettings.DEEPSEEK_MODEL, per_clause_durations[], raw_log, )模板起草class DraftService: async def generate( self, db: AsyncSession, user: User, template_id: str, variables: Dict[str, str], ) - Draft: 生成合同草稿校验变量、替换占位符并入库。 # 获取模板不存在则抛出异常 template: Template await template_service.get_by_id(db, template_id) # 获取模板中的变量定义 from app.models.template import TemplateContent content: TemplateContent template.content var_defs content.variables or [] # 校验必填变量 missing [v[key] for v in var_defs if v.get(required) and not variables.get(v[key])] if missing: raise RequiredVariableMissingError() # 校验变量类型 for v in var_defs: val variables.get(v[key]) if not val: continue vtype v.get(type) if vtype number: # 兼容数字类型或数字字符串 if not isinstance(val, (int, float)) and not re.match(r^-?\d(\.\d)?$, str(val)): raise VariableTypeError(f变量 {v[key]} 应为数字) elif vtype select: # 校验是否在下拉选项内 options v.get(options, []) if options and str(val) not in options: raise VariableTypeError(f变量 {v[key]} 不在合法选项内) # 替换模板中的变量占位符 result_content template.content.content for key, value in variables.items(): exact re.compile(r\{\{ re.escape(key) r\}\}) str_value str(value) if value is not None else result_content exact.sub(str_value or f[{key}], result_content) # 将未填写的占位符替换为 [待填写] result_content re.sub(r\{\{[\w\u4e00-\u9fa5]\}\}, [待填写], result_content) # 保存草稿到数据库 draft await draft_repo.create( db, idfdraft-{int(time.time() * 1000)}, user_iduser.id, template_idtemplate_id, titletemplate.title, contentresult_content, variablesvariables, ) # 模板使用次数 1 await template_service.increment_use(db, template_id) return draf五、代表性界面截图首页入口界面首页以三大功能卡片为核心分别对应「合同风险审查」「合同模板起草」「合同版本比对」[AI法律咨询]用户进入即可直达核心功能同时展示项目简介与核心能力降低用户决策成本。审查结果顶部展示合同综合评分与风险概览下方以卡片形式逐条展示风险条款支持展开查看原文每条条款附带风险等级、审查意见与修改建议底部提供 TXT/DOCX/PDF 多格式导出按钮。通过合同起草填写表单填写完成后一键生成合同全文可直接发起审查。系统自动生成完整合同文本。页面提供复制全文、下载 TXT、重新编辑、立即审查四个快捷操作。后台管理入口右上角头像下拉菜单包含个人资料、后台管理、退出登录选项。权限控制逻辑后台管理菜单仅对管理员角色可见普通登录用户看不到该选项做前端权限隐藏同时后端接口增加鉴权拦截即便普通用户直接输入 URL 访问后台路由也会被拒绝访问实现前后端双重权限校验。普通用户AI 法律咨询助手界面内置 ai 法律咨询可以帮助你了解维权的步骤和材料。还有其他页面如登录注册、个人资料、历史记录等就不展示了。注册目前仅支持通过邮箱进行注册另外还有一些功能没实现不完善我就没有部署到云服务器。当前现状✅ 已完成邮箱注册登录、RBAC 角色权限、合同模板起草、AI 风险审查、合同比对、TXT 导出、法律咨询对话、历史会话存储。⚠️ 尚未实现 / 不完善功能不支持图片上传部分边界交互、异常逻辑还需要打磨暂未部署到云服务器以本地开发测试版本运行。后续规划方向Web 端补齐补充图片上传、更多格式文档解析Word/PDF 优化完善异常分支处理完成后再进行云服务器部署。封装移动端 APP计划基于现有 Vue3 前端项目做移动端封装做成独立 App。
返回列表