拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Resume Matcher 面向 Agent 的文档导航体系:代码库结构、核心文档索引与任务驱动阅读路径

Resume Matcher 面向 Agent 的文档导航体系代码库结构、核心文档索引与任务驱动阅读路径【免费下载链接】Resume-MatcherThe #1 AI Harness for Building Resumes, PDFs, Cover Letters more, locally with 100 LLMs support.项目地址: https://gitcode.com/GitHub_Trending/re/Resume-MatcherResume Matcher 是一个用于根据职位描述JD定制简历Tailor Resume、生成 PDF、求职信与拓展信息的 AI 应用其代码库同时包含 FastAPI Python 后端与 Next.js React 前端。本文以仓库中的 Agent 文档入口 docs/agent/README.md 为核心骨架系统梳理这套为 AI Agent 与开发者设计的文档导航体系文档如何分类、代码库如何组织以及面对新任务、后端改动、前端改动、模板/PDF 改动四类典型场景时应当沿哪条文档阅读路径切入。读完本文你将获得一张可直接对照使用的文档地图知道每个文档解决什么问题、对应哪些源码与测试从而在 Resume Matcher 仓库中快速定位与安全改动。一、为什么需要一个面向 Agent 的文档索引大型代码库对人工开发者友好但对 AI AgentLLM 驱动的编码代理并不总是如此Agent 无法依赖 IDE 的目录树直觉也不宜在每次任务开始时通读全部源码。Resume Matcher 在docs/agent/下维护了一套project-specific项目专属参考文档其定位在 docs/agent/README.md 的开篇说明中非常明确该目录只收录与 Resume Matcher 本身绑定的文档通用、可复用的指南Swiss 设计系统、Next.js 性能优化被拆分为portable packs可移植包存放在 docs/portable/可整体搬出仓库应用到任何项目每个文档用一句话标注 Purpose用途让 Agent 在动手前 30 秒内判断该读哪篇。这种索引页 单主题文档 可移植包的三层结构本身就是一种值得借鉴的 Agent 友好文档实践入口文档只做导航、不重复内容分类按任务语义架构 / API / 设计 / 功能 / LLM 集成而非源码目录一一对应。二、文档体系总览五类文档 可移植包原索引将文档划分为以下类别下表完整继承其分类与用途说明并补充了对应的仓库相对路径核心文档Core docs文档用途仓库路径scope-and-principles规则、范围内/范围外事项docs/agent/scope-and-principles.mdquickstart安装、运行、测试命令docs/agent/quickstart.mdworkflowGit、PR、测试约定docs/agent/workflow.mdcoding-standards前端/后端编码规范docs/agent/coding-standards.md架构文档Architecture文档用途仓库路径backend-architecture后端模块、API、服务docs/agent/architecture/backend-architecture.mdbackend-guide后端逐模块导览docs/agent/architecture/backend-guide.mdfrontend-architecture组件、页面、状态docs/agent/architecture/frontend-architecture.mdfrontend-workflow前端用户流程docs/agent/architecture/frontend-workflow.mdprompt-workflow-designImprover 流水线设计已废弃保留作历史参考docs/agent/architecture/prompt-workflow-design.mdAPI 文档文档用途仓库路径front-end-apisAPI 契约docs/agent/apis/front-end-apis.mdapi-flow-maps请求/响应流程docs/agent/apis/api-flow-maps.mdbackend-requirements后端行为需求docs/agent/apis/backend-requirements.md设计文档Resume Matcher 专属设计文档用途仓库路径template-system简历模板架构docs/agent/design/template-system.mdpdf-template-guidePDF 渲染流水线docs/agent/design/pdf-template-guide.mdprint-pdf-design-spec打印/PDF 设计规范docs/agent/design/print-pdf-design-spec.mdresume-template-design-spec简历模板设计规范docs/agent/design/resume-template-design-spec.mdtemplates/swiss-single-spec单栏 Swiss 模板规范docs/agent/design/templates/swiss-single-spec.mdtemplates/swiss-two-column-spec双栏 Swiss 模板规范docs/agent/design/templates/swiss-two-column-spec.md设计系统本身色彩、组件、反模式属于可移植包见 docs/portable/swiss-design-system/。功能文档Features文档用途仓库路径custom-sections动态自定义区块docs/agent/features/custom-sections.mdresume-templates模板类型与控制项docs/agent/features/resume-templates.mdadding-resume-templates如何新增模板docs/agent/features/adding-resume-templates.mdenrichmentAI 信息补全流程docs/agent/features/enrichment.mdjd-match职位描述匹配docs/agent/features/jd-match.mdi18n国际化docs/agent/features/i18n.mdi18n-preparationi18n 搭建笔记docs/agent/features/i18n-preparation.mdLLM 集成文档用途仓库路径llm-integration通过 LiteLLM 的多提供商 AI 接入docs/agent/llm-integration.md可移植包存放于本目录之外包用途仓库路径swiss-design-system完整 Swiss 风格设计系统前端工作的必读材料docs/portable/swiss-design-system/README.mdnextjs-performanceNext.js 15 性能优化前端工作的必读材料docs/portable/nextjs-performance/README.md值得注意的是docs/agent/features/application-tracker.md求职申请追踪看板也存在于该目录中与仓库中apps/backend/app/routers/applications.py及前端 apps/frontend/components/tracker/ 等组件对应是功能文档体系中未被索引表收录但实际存在的一部分。三、项目结构速览backend 与 frontend 双应用原索引给出了仓库的顶层骨架docs/agent/README.md 的 Project Structure 一节这里完整继承并补充真实目录细节apps/ ├── backend/ # FastAPI Python │ ├── app/ │ │ ├── main.py # 入口lifespanTinyDB→SQLite 迁移、旧 key 折叠 │ │ ├── routers/ # API 端点health/config/resumes/jobs/applications/enrichment │ │ ├── services/ # 业务逻辑parser/improver/cover_letter/refiner │ │ ├── schemas/ # Pydantic 模型 │ │ ├── prompts/ # LLM 提示词模板 │ │ ├── config.py # Pydantic 设置 加密 API key 读写 │ │ ├── crypto.py # Fernet 加密/解密 │ │ ├── database.py # 异步 SQLAlchemy/SQLite 门面返回纯 dict │ │ ├── db_engine.py # SQLite 引擎/会话工厂 PRAGMA │ │ ├── llm.py # LiteLLM 多提供商封装 │ │ └── pdf.py # Playwright PDF 渲染 │ └── data/ # 数据库存储 │ └── frontend/ # Next.js React ├── app/ # 页面(default)/、print/ ├── components/ # UI 组件ui/builder/preview/resume/tailor/tracker └── lib/ # 工具、API client、context从 apps/backend/app/ 的实际源码看后端不止上表列出的文件还包含config_cache.py、db_engine.py、models.py、pdf.py以及scripts/migrate_tinydb_to_sqlite.py一次性 TinyDB 导入器prompts/目录下除了templates.py还有enrichment.py、refinement.py、resume_wizard.py等按功能拆分的提示词文件。前端在components/下还新增了enrichment/、resume-wizard/、tailor/、tracker/、settings/等目录说明该索引中的结构图是稳定主干具体以各架构文档与源码为准。四、任务驱动的文档阅读路径How to Use原索引以四类典型任务给出了阅读顺序这是整个文档体系最实用的部分完整继承如下并补充每步读取的目的新任务New tasks先读 scope-and-principles了解哪些事能做、哪些禁止→ quickstart掌握安装/运行/测试命令→ workflow遵守提交与 PR 约定。后端改动Backend changes读 backend-architecture模块与 API 全貌→ front-end-apisAPI 契约→ llm-integrationLLM 调用方式。前端改动Frontend changes读 frontend-architecture → 可移植包 swiss-design-system → 可移植包 nextjs-performance → coding-standards。模板/PDF 改动Template/PDF changes读 pdf-template-guide → template-system。这套路径的设计哲学是按任务聚类、按依赖排序后端改动链把架构怎么组织→ 契约暴露什么→ LLM 集成AI 怎么调串成一条完整链路前端改动链则强制先读可移植设计系统与性能规范再读编码规范避免 UI 改动违反 Swiss 风格约束。五、核心文档深入Scope、Quickstart 与 Workflow5.1 项目是什么scope-and-principlesdocs/agent/scope-and-principles.md 是Agent 行为规则的权威来源Canonical source其技术栈描述与仓库源码高度一致后端FastAPI Python 3.13通过 LiteLLM 支持多提供商 LLM前端Next.js React 19注意该文档写 Next.js 16而 frontend-architecture 写 Next.js 15可移植包标题为 Next.js 15 performance optimizations两处版本表述以 apps/frontend/package.json 实际依赖为准采用 Swiss International Style 设计数据库SQLite通过异步 SQLAlchemyaiosqlite访问PDF 生成通过 Playwright 调用无头 Chromium。文档还定义了不可妥协的规则Non-Negotiable Rules所有前端改动必须遵循 Swiss 设计系统所有后端函数必须带类型提示type hints提交前必须运行npm run lint与npm run formatPrettier错误处理后端在服务端记录详细错误、向客户端返回通用消息前端使用错误边界Error Boundary与用户友好的错误状态安全绝不在客户端响应中暴露 API key 或敏感数据共享资源初始化使用asyncio.Lock()可变默认值必须使用copy.deepcopy()。范围外Out of Scope事项明确列出不得修改.github/workflows/、不得未经明确请求改动 CI/CD 配置、不得改动 Docker 构建行为、不得删除或禁用测试。5.2 快速开始quickstartdocs/agent/quickstart.md 给出了可直接执行的完整命令序列前置要求Node.js 22、Python 3.13、uvPython 包管理器。安装从仓库根目录执行# 后端 cd apps/backend uv sync # 前端 cd apps/frontend npm install开发两个终端并行# 终端 1后端 cd apps/backend uv run uvicorn app.main:app --reload --port 8000 # 终端 2前端 cd apps/frontend npm run dev质量检查# 在 apps/frontend 下 npm run lint # 前端 lint npm run format # Prettier 格式化后端测试cd apps/backend uv run pytest环境变量初始化# 后端 cp apps/backend/.env.example apps/backend/.env # 前端 cp apps/frontend/.env.sample apps/frontend/.env.local首次使用流程打开 http://localhost:3000/settings选择 AI 提供商并输入 API key点击 Test Connection对应POST /api/v1/config/llm-test端点上传第一份简历5.3 工作流约定workflowdocs/agent/workflow.md 定义了提交、PR 与测试规范提交信息使用简洁的句子式主题如Add custom funding link to FUNDING.yml若使用前缀采用祈使句type: summary格式用Fixes #123关联 issuePR 要求在描述中引用 issueschema 或 prompt 改动必须显式标注以便 reviewer 对下游 Agent 做冒烟测试列出本地验证命令UI/API 改动附截图测试约定前端测试以*.test.tsx命名仓库中 apps/frontend/tests/ 等真实遵循此约定后端测试用test_*.py命名置于apps/backend/tests/需使用匿名化的简历/职位 fixtures见 apps/backend/tests/conftest.pyDefinition of Done代码可编译、lint 通过、新功能有测试、UI 遵循 Swiss 包、schema/prompt 改动在 PR 中标注、UI 改动附截图、以 PR 中列出的命令完成本地验证。六、架构文档后端与前端的两份地图6.1 后端架构backend-architecturedocs/agent/architecture/backend-architecture.md 是对 apps/backend/app/ 源码结构的权威说明几个关键设计值得展开API 端点一览均挂载于/api/v1前缀类别端点说明健康GET /health存活探针不调用 LLM状态GET /status完整系统状态LLM 探针 DB 统计各检查隔离 → 部分失败仍返回 200 与降级状态配置GET/PUT /config/llm-api-keyLLM 配置不再持久化 key配置POST /config/llm-test测试连接配置GET/POST/DELETE /config/api-keys按提供商加密存储的 API key简历POST /resumes/upload、GET /resumes、GET /resumes/list、POST /resumes/improve、PATCH /resumes/{id}、GET /resumes/{id}/pdf、DELETE /resumes/{id}简历全生命周期职位POST /jobs/upload、GET /jobs/{id}职位描述应用GET/POST /applications、GET/PATCH/DELETE /applications/{id}、PATCH /applications/bulk、POST /applications/bulk-deleteKanban 追踪器数据库设计SQLite 文件位于data/resume_matcher.db由database.py异步门面返回纯 dict而非 ORM 行、models.py声明式BaseResume/Job/Improvement/Application/ApiKey模型与db_engine.py引擎/会话工厂协作。数据库有两个引擎、一个文件模块级异步引擎服务文档表与applications表同步引擎服务加密的api_keys表——因为该表在同步的 LLM 热路径get_llm_config→load_config_file→resolve_api_key上被读取异步不必穿透到llm.py。源码 apps/backend/app/db_engine.py 中可见两个引擎连接时都执行PRAGMA journal_modeWAL、PRAGMA foreign_keysON、PRAGMA busy_timeout5000。关键不变量与迁移单一主简历single-master通过asyncio.Lockcreate_resume_atomic_masteris_master上的部分唯一索引保证动态流水线字段preview_hash/preview_hashes、job_keywords、company/role存放在metadata_jsonJSON 列中读取时扁平化Application通过UniqueConstraint在(job_id, resume_id)上去重一次性导入器scripts/migrate_tinydb_to_sqlite.py启动 lifespan 时若存在旧 TinyDB 文件data/database.json且 SQLite 为空则导入行并重命名为database.json.migrated可回滚工件幂等——SQLite 已有数据则跳过加密 API keycrypto.py使用 Fernet 对称加解密密钥位于data/.secret_key自动生成、chmod 600、gitignored、原子写入明文只存在于内存migrate_legacy_keys()在启动时将旧明文 key 折叠进加密存储幂等、不覆盖。LLM 集成llm.py提供商为 OpenAI、Anthropic、Gemini、DeepSeek、OpenRouter、Ollama。三个核心异步函数await check_llm_health(config) # 30s 超时 await complete(prompt, ...) # 120s 超时 await complete_json(prompt, ...) # 180s 超时JSON 模式 重试特性包括API key 直接传参避免os.environ竞态受支持提供商自动启用 JSON 模式带更低温度的重试括号匹配 JSON 提取。源码 apps/backend/app/llm.py 进一步证实了超时常量30/120/180 秒以及MAX_JSON_EXTRACTION_RECURSION 10、MAX_JSON_CONTENT_SIZE 1MB、DEFAULT_JSON_MAX_TOKENS 8192等安全上限。配置优先级非机密配置provider/model/base/features存放在data/config.json优先级高于环境变量API key 绝不写入config.json只加密存于 SQLiteapi_keys表仅在读取时注入配置字典。6.2 前端架构与工作流frontend-architecture / frontend-workflowdocs/agent/architecture/frontend-architecture.md 与 docs/agent/architecture/frontend-workflow.md 共同勾勒了前端全貌核心用户流Dashboard → Upload Master Resume → Tailor for Job → View/Edit → Download PDF主要页面/dashboard主简历卡片 定制简历瓦片状态机loading | pending | processing | ready | failed窗口聚焦时自动刷新用 localStorage 的master_resume_id记录主简历/builder左侧编辑器表单 格式控制右侧 WYSIWYG 分页预览Resume / Cover Letter / Outreach 三个标签页自动保存到 localStorage数据优先级为 URL 参数 → Context → localStorage → 默认值/tailorJD 文本域最少 50 字符流程为POST /jobs/upload→POST /resumes/improve→ 跳转/resumes/[new_id]/settings6 个提供商选择、API key 输入、系统状态缓存30 分钟刷新打印路由/print/resumes/[id]、/print/cover-letter/[id]由无头 Chrome 为 PDF 渲染支持 template、pageSize、margins、spacing 查询参数。状态管理StatusCacheProvider缓存系统状态30 分钟自动刷新 乐观计数更新LanguageProvider管理内容生成语言en、es、zh、ja对应仓库中的 apps/frontend/lib/context/language-context.tsx 与 apps/frontend/i18n/config.ts。localStorage 键master_resume_id主简历 UUID、resume_builder_draft表单自动保存、resume_builder_settings模板偏好。分页系统usePagination钩子计算分页断点尊重.resume-item边界、防止孤立标题orphaned headers、150ms 防抖分页规则为区块可以跨页、单个条目保持完整、页面至少 50% 满才断页、标题永不孤立。关键 CSS 规则PDF 生成依赖globals.css中的打印白名单media print { body * { visibility: hidden !important; } .resume-print, .resume-print * { visibility: visible !important; } .cover-letter-print, .cover-letter-print * { visibility: visible !important; } }七、API 文档契约与请求/响应流程docs/agent/apis/api-flow-maps.md 以流程图形式呈现了各端点的内部调用链是排查问题的第一手材料。以下是几个最关键的流程完整继承并适当注解简历上传POST /api/v1/resumes/upload ├── 校验文件PDF/DOCX≤4MB ├── parse_document() → Markdown ├── db.create_resume(statusprocessing) ├── parse_resume_to_json() → LLM │ ├── 成功statusready │ └── 失败statusfailed └── 返回 {resume_id}简历定制ImprovementPOST /api/v1/resumes/improve ├── 从 DB 取简历 职位 ├── extract_job_keywords() → LLM ├── improve_resume() → LLM ├── [若启用] generate_cover_letter() → LLM ├── [若启用] generate_outreach_message() → LLM ├── [若启用] generate_interview_prep() → LLM ├── db.create_resume(improved) ├── db.create_improvement() └── 返回 {data, cover_letter, outreach_message, interview_prep}PDF 生成GET /api/v1/resumes/{id}/pdf ├── 从 DB 取简历 ├── 构造 URL{frontend}/print/resumes/{id}?{params} ├── Playwright 渲染等待 .resume-print └── 返回 PDF 字节系统状态部分失败仍 200GET /api/v1/status # 每项检查隔离 → 200部分/降级绝不 500 ├── try: get_llm_config() │ ├── llm_configured api_key 已设置 或 provider ∈ {ollama, openai_compatible} │ └── check_llm_health() → llm_healthy # 此处失败只降级该字段 ├── try: db.get_stats() # 失败 → 空统计仍 200 └── 返回 {status, llm_configured, llm_healthy, has_master_resume, database_stats}按提供商加密的 API keyGET /api/v1/config/api-keys └── 返回 {providers: [{provider, configured, masked_key}]} # 始终掩码 POST /api/v1/config/api-keys ├── 对每个提供的 keyFernet 加密 → upsert 进 SQLite api_keys 表 # 其他提供商 key 不受影响 └── 返回 {message, updated_providers} DELETE /api/v1/config/api-keys/{provider} # 删除单个提供商 key DELETE /api/v1/config/api-keys?confirm... # 清空所有 key求职追踪器Application TrackerGET /applications按 7 个状态键分组返回saved / applied / no_response / response / interview / accepted / rejected手动新增时若缺 company/role 会做一次 best-effort 的extract_job_keywords()LLM 调用PATCH /applications/{id}时服务端会重排position。值得注意的自动创建逻辑POST /resumes/improve/confirm及旧版POST /resumes/improve在持久化定制简历后会自动创建一个applied卡片——这是 best-effort 行为追踪器失败不会破坏定制主流程company/role 复用缓存的 keyword 提取结果不产生额外 LLM 调用。八、设计文档模板系统与 PDF 渲染8.1 模板系统template-systemdocs/agent/design/template-system.md 完整列出了 7 套模板仓库中对应文件见 apps/frontend/components/resume/模板布局适用场景swiss-single全宽纵向1–2 页简历swiss-two-column65% 主栏 35% 侧栏内容密集modern单栏 强调色标题彩色单栏modern-two-column65% 主栏 35% 侧栏 强调色彩色密集内容latex单栏、衬线、规则线标题经典/学术简历clean单栏、极简无衬线低调现代简历vivid63% 主栏 37% 侧栏 强调色Awesome-CV 风格彩色简历模板设置的权威定义在 apps/frontend/lib/types/template-settings.tsTemplateSettings、DEFAULT_TEMPLATE_SETTINGS及 CSS 变量映射当前形态包括pageSizeA4/LETTER、margins各 5–25mm、spacingsection/item/lineHeight 各 1–5 级、fontSizebase/headerScale 1–5 级headerFont/bodyFont 可选 serif/sans-serif/mono、compactMode、showContactIcons、accentColorblue/green/orange/red适用于 modern、modern-two-column、vivid。自定义区块由AddSectionDialog支持三种类型textGenericTextForm用于 Objective、statement、itemListGenericItemForm用于 Publications、research、stringListGenericListForm用于 Hobbies、interests。间距变量通过 CSS 变量计算--section-spacing: calc(4px * var(--spacing-level))、--item-spacing: calc(2px * var(--spacing-level))、--line-height: calc(1.4 0.1 * var(--line-height-level))。新增模板的步骤docs/agent/features/adding-resume-templates.md 有更详细说明创建components/resume/resume-{name}.tsx实现TemplateProps接口从components/resume/index.ts导出加入FormattingControls选择器生成预览缩略图。8.2 PDF 渲染流水线pdf-template-guidePDF 渲染使用 Playwright 无头 Chromium核心函数为render_resume_pdf(url, page_size, selector.resume-print)。关键约束是globals.css中的打印类白名单见上文 6.2这解释了为什么前端路由中单独存在print/目录打印路由是专为 PDF 渲染设计的、去交互的页面形态。九、LLM 集成细节LiteLLM、JSON 模式与重试docs/agent/llm-integration.md 提供了多提供商接入的完整说明其中几个关键实现值得强调提供商矩阵Ollama本地、免费、OpenAIGPT-5 Nano、GPT-4o、AnthropicClaude Haiku 4.5、GeminiGemini 3 Flash、OpenRouter多模型聚合、DeepSeekDeepSeek Chat。API key 传参方式直接传给litellm.acompletion()的api_key参数而非os.environ——后者在异步上下文中存在竞态风险# 正确 await litellm.acompletion( modelmodel, messagesmessages, api_keyapi_key # 直接传参 ) # 错误 —— 不要在异步代码中使用 os.environ os.environ[OPENAI_API_KEY] key # 竞态风险JSON 模式complete_json()对支持的提供商OpenAI、Anthropic、Gemini、DeepSeek、主流 OpenRouter 模型自动启用response_format{type: json_object}JSON 完成带 2 次自动重试且温度逐次降低第 1 次 0.1、第 2 次 0.0_extract_json()使用健壮的括号匹配算法处理畸形响应、Markdown 代码块、边界情况并带有递归保护源码中MAX_JSON_EXTRACTION_RECURSION 10。超时配置源码 apps/backend/app/llm.py 与文档一致健康检查 30s、普通完成 120s、JSON 操作 180s。提示词指南新提示词加入 apps/backend/app/prompts/templates.py使用{variable}单大括号替换结构化输出必须给出示例 JSON schema指令保持简洁Output ONLY the JSON object, no other text。健康检查注意Docker 健康检查必须使用/api/v1/health而非/health这一点在部署场景下容易被忽略。十、可移植包独立于项目的最佳实践沉淀索引特别强调两个可移植包存放于 docs/portable/swiss-design-system完整 Swiss 风格设计系统tokens、组件、布局、反模式前端工作的必读材料其中的 tokens.md 与 components.md 是触碰 UI 前的强制阅读项见 scope-and-principles 规则第 1 条nextjs-performanceNext.js 性能优化实践水合瀑布、包体积、Server Actions 安全、服务端性能对 apps/frontend/ 的改造工作具有直接指导价值。这种把通用知识做成可移植包、项目专属知识留在 agent 目录的划分是文档体系的关键设计它让跨项目复用的内容不被项目细节污染也让 Agent 只需在项目内查找专属约定。十一、总结如何使用这份文档地图对任何要在 Resume Matcher 仓库中工作的 Agent 或开发者推荐的实践路径是新任务起步scope-and-principles→quickstart→workflow先建立行为边界、工具命令与协作约定定位问题域根据任务类型选择架构后端/前端、API契约/流程、设计模板/PDF或功能文档配合 apps/backend/tests/ 与 apps/frontend/tests/ 中的测试用例验证行为深入实现通过各文档给出的源码相对路径如 apps/backend/app/llm.py、apps/backend/app/db_engine.py、apps/frontend/lib/types/template-settings.ts直达底层实现遵循交付标准以workflow.md的 Definition of Done 为完成标准涉及 schema/prompt 改动时在 PR 中显式标注。这份索引的价值在于它把代码库知识组织成了可检索、可排序、按任务导航的结构既服务于人类开发者也服务于需要高效定位代码的 AI Agent——这也是它被命名为 Agent Documentation Index 的原因所在。【免费下载链接】Resume-MatcherThe #1 AI Harness for Building Resumes, PDFs, Cover Letters more, locally with 100 LLMs support.项目地址: https://gitcode.com/GitHub_Trending/re/Resume-Matcher创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门