day10-FastAPI-bossApi项目-搜索职位,简历,岗位详情
招聘平台的核心体验浓缩在一条链路上求职者搜到好职位 → 查看详情 → 一键投递 → 企业在简历中心筛选处理。这条链路一旦有任何断点产品就转不起来。本文复盘我在一天内把这条链路从后端到前端完整打通、并顺手修复 9 个真实 Bug 的全过程所有代码均来自 FastAPI Tortoise ORM Vue3 实战项目。技术栈延续一贯风格FastAPI Tortoise ORM异步做业务Elasticsearch做搜索Vue3 Element Plus做前端API 统一三层分离Router → Service → Model。二、后端四大功能模块2.1 ES 职位搜索服务job_search_service.py基于boss_job_index_v2索引支持多字段加权搜索与高亮「只搜招聘中职位」是关键业务约束——草稿/关闭的职位不应出现在求职者搜索结果里。2.2 职位详情 相似推荐job_detail_service.pyget_job_detail()用 4 表联合查询Job Enterprise EnterpriseInfo IndustryPosition把部门枚举、企业规模、融资阶段映射成中文名get_similar_jobs()按「同城市 同部门」推荐相似职位并排除同企业自身。2.3 简历投递resume_submission数据模型用unique_together(job_id, job_seeker_id)防重复投递状态机设计Service 层submit_resume()会校验职位存在且招聘中、检查重复已撤回可重投get_enterprise_resumes()给企业提供「求职者基本信息 简历摘要」并支持各状态计数统计。2.4 简历中心企业端GET /resume/center收到的简历列表GET /resume/center/stats统计概览总数 / 今日新增 / 未读 / 各状态分布PUT /resume/center/status企业更新状态标不合适时强制填原因三、前端四大模块对接求职者端boss-candidate-ui与企业端boss-company-ui同步对接求职者端JobList.vue搜索接口替换 mock处理字符串薪资格式化、loading / 空态JobDetail.vue拉取详情 相似职位投递按钮调submitResume({job_id})DeliveryRecord.vue我的投递记录canWithdraw(status)仅 1/2 可撤回企业端ResumeList.vue简历中心列表 统计卡片总数 / 今日新增 / 待处理ResumeDetail.vue解析路由query.data渲染真实字段改状态时 status6 弹窗强制填原因四、9 个真实 Bug 修复复盘重点Bug 1下拉框选择后不显示值原因Element Plus 中el-form-item嵌套带prop的内层 form-itemselect 值渲染有 bug。修复去掉外层 form-item改用.form-group-label分组标签 label-width0并排布局。Bug 2发布职位鉴权死循环原因后端/job/save用get_job_info解析teamToken但企业端用户只有companyToken→ 跳转团队登录 → 点企业登录 → 回发布页 → 死循环。修复新增POST /job/enterprise-save用get_enterprise_info解析 companyToken前端jobSaveEnterprise()改用 companyToken 提交。Bug 3团队登录验证码 500原因/enterprise/team/send_code业务异常raise Exception(该手机号未注册招聘团队成员)未被捕获 → 500。修复登录类 4 个接口统一加 try/except业务异常返回{code:0, message}而非 500。Bug 4recruit_team_id NOT NULL原因Job 模型该字段原非空企业端发布传 None 触发ValueError。修复模型加nullTrue 执行ALTER TABLE t_job MODIFY COLUMN recruit_team_id INT NULL。Bug 5团队成员管理是 mock问题邀请成员只弹假成功后端根本没有 CRUD 接口。修复新增 4 个接口invite / members / member status / delete Service 层含手机号脱敏、中文状态映射、软删除前端 TeamMembers.vue 全量对接真实 API。Bug 6发布后列表不回显双重根因① 前端if (!teamLoggedIn) return无 teamToken 直接不请求② 后端/job/list按recruit_team_id过滤企业发布的职位该字段为 NULL 也查不到。修复新增GET /job/enterprise-list按 enterprise_id 查全部职位前端改用jobListEnterprise()。Bug 7删除职位待补全本次新增现象PositionList.vue 的暂停/关闭/删除三个操作是 mock 成功提示。修复后端已有PUT /job/enterprise/{id}/status与DELETE /job/enterprise/{id}前端补jobUpdateStatus/jobDelete并接真实 API 操作后刷新列表。Bug 8搜索一直 loading本次新增重点现象求职者端输入关键词点搜索页面转圈不出结果。根因搜索走 ESES 未运行时请求挂起。修复新增search_db_fallback()ES 异常时自动降级为数据库查询返回格式与 ES 完全一致前端零改动降级搜索支持关键词模糊匹配、城市/经验/学历筛选、分页排序保证 ES 宕机时搜索依然可用——这是生产环境必须具备的兜底能力。Bug 9搜索页无分页 / 错误热标签修复JobList.vue 重写补充分页组件、经验筛选、重置按钮、清空筛选空态、薪资橙色高亮、卡片 hover、路由参数监听、回车搜索移除所有招聘中职位都标热的错误逻辑。五、架构总结与技术沉淀六、写在最后一天内把「搜索 → 投递 → 简历中心」这条主线打通最值得记住的不是写了多少接口而是每一次页面转圈/白屏/500背后都是一个具体的边界没处理好嵌套组件、Token 类型、字段可空、服务降级、mock 占位。把这些都补上产品才真正能用。下一步可以继续做搜索建议(Suggestion)、简历智能解析、投递状态实时通知(WebSocket)。