人才搜索与招聘流程
这是 youteacher_web 面向招聘方的核心:雇主或招聘顾问搜索教师档案,消耗配额(quota)来解锁某位教师被遮挡的详细信息,然后通过联系或职位邀请去触达对方。整个功能建立在应用的六边形分层之上——纯粹的 use case、一个 gateway 端口(port)、以及由一个 React hook 接线进来的具体 API 适配器。
它的形状
这个功能把「发生了什么」和「它如何与后端对话」分开:
- Use case(应用层)各自只持有一个操作和一个依赖。
SearchTalentsUseCase接收筛选条件、页码、每页数量和一个可选的AbortSignal,然后委托给 gateway。UnlockTalentUseCase、FetchViewerQuotaUseCase、FetchTalentDetailUseCase、SendContactUseCase、SendInviteUseCase都遵循同样的「单方法」模式。 - 端口
TalentSearchGateway是 use case 所依赖的契约,声明了search、fetchDetail、sendContact、sendInvite、unlock、fetchUnlocked。另有一个ViewerGateway声明fetchQuota。具体实现落在基础设施层,是唯一知道 HTTP 细节的地方。 - 依赖注入是一个 hook,而不是一套框架。
useTalentSearchService用 memo 缓存具体的 API gateway,并围绕它们构造每个 use case,对外暴露一个稳定的useCases对象。替换适配器时,use case 一字不用改。
搜索
useTalentSearch 持有页面状态:结果列表、分页,以及搜索表单(自由文本查询、可授课状态、技能、地点,以及「相关度 / 最新」排序)。buildFilters 只把用户实际填了的字段收进筛选对象。
搜索只在访问者已授权时才运行。handleSearch 重置到第 1 页,执行 use case,存下结果和总页数,并且——在宽屏桌面视口下——自动选中第一条结果,让详情面板不至于空着。handleLoadMore 拉取下一页并追加。限流(rate-limit)响应会被专门捕获,以友好的 toast 提示呈现,而不是抛出原始错误。
解锁、配额与触达
教师的联系方式是被遮挡的。UnlockTalentUseCase 接收一个 talent id 和访问者类型(雇主或招聘顾问);按其契约,首次解锁消耗一个单位配额,之后对同一位教师的调用是幂等的——不会被重复扣费。FetchViewerQuotaUseCase 读取访问者剩余的配额,gateway 的 fetchUnlocked 返回哪些教师已经解锁,这样 UI 能显示已解锁状态而无需再次扣费。
解锁之后存在两个对外动作:sendContact 把一段消息发给教师,sendInvite 把一个职位(id,以及可选的标题和消息)附在触达里。TalentDetailPane 渲染被选中的教师——头像、姓名、一句话简介、可授课状态、个人简介、技能、期望地点、教龄,以及可核验的资质凭证——并把「已解锁 / 已联系 / 已邀请」的状态交给 TalentActions 区块,由它按访问者类型驱动解锁、联系、邀请按钮。
选中一位教师时会重新拉取最新详情;已下架的档案会从列表中移除,无权查看的则清空面板——这个功能把「不再可见」当作一种正常状态,而非崩溃。
本节内容
- 属于 ddd-hexagonal-architecture ——本功能所构建于其上的分层
- 同一道门在 profile 服务侧的实现位于
youteacher_profile(人才解锁与配额执行)