# 岗位名称联想接口文档 ## 1. 接口说明 根据用户输入的岗位关键词,从有效岗位名称预先生成的 IK 分词缓存中查询联想结果,返回匹配的 IK 分词和包含该分词的完整岗位名称,供首页搜索框快速选择。 接口查询 Redis 缓存,不在用户输入时访问岗位数据库。 ## 2. 接口地址 **后端接口:** `GET /app/job/suggest` **前端代理地址:** `GET /api/app/job/suggest` 前端页面通过代理地址调用,代理转发到后端 `/app/job/suggest`。 ## 3. 请求参数 请求方式:`GET` 请求参数通过 Query String 传递。 | 参数名 | 类型 | 必填 | 默认值 | 说明 | |--------|------|------|--------|------| | keyword | String | 否(建议传入) | - | 用户输入的岗位关键词或 IK 分词前缀。未传、为空或仅包含空格时返回空数组 | | limit | Integer | 否 | 10 | 返回结果数量,服务端限制在 1~20 之间,超过 20 按 20 返回,小于 1 按 1 返回 | ## 4. 请求示例 ```http GET /app/job/suggest?keyword=后端&limit=10 ``` 前端代理调用: ```http GET /api/app/job/suggest?keyword=后端&limit=10 ``` 使用 cURL 调用: ```bash curl "http://localhost:8080/app/job/suggest?keyword=%E5%90%8E%E7%AB%AF&limit=10" ``` 如果通过前端代理访问: ```bash curl "http://47.111.103.66/shihezi/api/app/job/suggest?keyword=%E5%90%8E%E7%AB%AF&limit=10" ``` > 实际部署时请根据前端代理配置确认 `/shihezi` 前缀和后端服务地址。 ## 5. 响应参数 | 参数名 | 类型 | 说明 | |--------|------|------| | code | Number | 状态码,200 表示成功 | | msg | String | 提示信息 | | data | Array | 联想结果列表,结果内容为 IK 分词或完整岗位名称 | ## 6. 成功响应示例 请求: ```http GET /app/job/suggest?keyword=后端&limit=10 ``` 响应: ```json { "code": 200, "msg": "操作成功", "data": [ "后端", "后端工程师", "高级Java后端开发工程师" ] } ``` ## 7. 空关键词响应 当 `keyword` 未传、为空或仅包含空格时,接口直接返回空数组。 请求: ```http GET /app/job/suggest?keyword= ``` 响应: ```json { "code": 200, "msg": "操作成功", "data": [] } ``` ## 8. 无匹配结果响应 当输入关键词没有匹配的 IK 分词时,接口返回空数组。 请求: ```http GET /app/job/suggest?keyword=不存在的岗位&limit=10 ``` 响应: ```json { "code": 200, "msg": "操作成功", "data": [] } ``` ## 9. 返回规则 ### 9.1 IK 分词规则 定时任务从有效岗位名称中使用 IK `smart` 模式分词。例如: ```text 岗位名称:高级Java后端开发工程师 IK 分词:高级、java、后端、开发、工程师 ``` 缓存中的词项只来自 IK 分词结果,不额外生成单字、字符片段或其他自定义前缀。 用户输入会进行统一标准化处理: - 全角字符转换为半角字符; - 英文字母转换为小写; - 去除空白字符。 标准化后,接口对缓存中的 IK 分词进行前缀匹配。例如输入 `工程` 可以匹配以 `工程` 开头的 IK 词项。 ### 9.2 完整岗位名称规则 为了提升联想效果,接口不仅返回匹配到的 IK 分词,还会返回包含该分词的完整岗位名称。 例如 Redis 中存在以下映射: ```text 后端 -> 高级Java后端开发工程师 工程师 -> 高级Java后端开发工程师、后端工程师 ``` 输入 `后端` 时,接口会将 `后端` 和相关完整岗位名称合并返回,并自动去重。 ### 9.3 结果数量 - 默认最多返回 10 条; - `limit` 最大为 20; - 返回结果包含 IK 分词和完整岗位名称,二者合计不超过 `limit`; - 结果自动去重; - 没有结果时返回空数组,不返回 `null`。 ## 10. 数据缓存和定时重建 Redis 使用 Hash 保存岗位名称联想数据: ```text Redis Key:app:job:title:suggest ``` 数据结构: | Hash 内容 | 说明 | |-----------|------| | field | IK 分词,例如 `后端`、`工程师` | | value | 包含该分词的完整岗位名称列表 | 定时任务只处理有效岗位,岗位有效条件如下: ```sql del_flag = '0' AND job_status = '0' AND job_title IS NOT NULL AND trim(job_title) <> '' ``` Quartz 定时任务调用目标: ```text jobCron.rebuildJobTitleSuggest() ``` 应用启动时会初始化一次缓存,之后由 Quartz 定时任务按配置周期重建。重建时先写入临时缓存,完成后再替换正式缓存,避免接口读取到不完整数据。 ## 11. 前端接入建议 首页搜索框可以按以下方式接入: 1. 将普通输入框改为支持下拉选项的 `AutoComplete` 或自定义下拉组件。 2. 用户输入停止约 250ms 后调用接口,避免每次键盘事件都请求后端。 3. 输入为空时清空下拉选项,不调用接口。 4. 调用 `/api/app/job/suggest`,将返回的 `data` 数组直接转换为下拉选项。 5. 用户点击某个联想项时,将选中的完整文本回填到搜索框,并执行岗位搜索。 6. 用户直接回车或点击搜索按钮时,仍使用搜索框当前文本执行搜索。 7. 岗位列表页使用与原有搜索接口一致的岗位名称参数,例如 `name`,将完整岗位名称作为搜索条件传递。 8. 建议使用请求序号、取消请求或其他方式处理异步请求顺序,避免旧请求结果覆盖用户最新输入的结果。 前端请求示例: ```ts const response = await get('/api/app/job/suggest', { params: { keyword: value, limit: 10, }, }); const options = (response.data || []).map((item: string) => ({ value: item, label: item, })); ``` 选择联想结果后,建议以完整岗位名称进行搜索: ```ts handleSearch(selectedValue); // selectedValue 例如:高级Java后端开发工程师 ```