Appearance
嘉宾管理
GET /api/open/v1/guests — 嘉宾列表
权限:open:guest:read
查询参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| page | int | 否 | 页码,默认 1 |
| page_size | int | 否 | 每页条数,默认 20,最大 100 |
| keyword | string | 否 | 搜索关键词(姓名/手机号) |
| gender | string | 否 | 性别筛选:male / female |
| workplace | string | 否 | 工作地筛选 |
| status | string | 否 | 状态筛选:incomplete / available / matching / matched / archived |
| company_id | int | 否 | 按所属公司筛选 |
| order_by | string | 否 | 排序字段:created_at(默认)/ updated_at |
| order_dir | string | 否 | 排序方向:desc(默认)/ asc |
响应示例:
json
{
"code": 200,
"message": "success",
"data": {
"list": [
{
"id": 1001,
"name": "张三",
"gender": "male",
"age": 28,
"phone": "13800138000",
"workplace": "上海",
"height": 178,
"weight": 72,
"education": "本科",
"occupation": "软件工程师",
"income_level": "20-50万",
"marital_status": "未婚",
"requirement": "希望对方年龄在25-30之间...",
"requirement_tags": {
"age_min": 25,
"age_max": 30,
"height_min": 160
},
"photos": ["https://oss.ailian.com/guest/1001.jpg"],
"company_id": 5,
"status": "available",
"created_at": "2025-06-15 10:30:00",
"updated_at": "2025-07-20 14:22:00"
}
],
"total": 156
}
}注意:开放接口默认返回完整数据(不脱敏)。如你的客户端被单独配置了脱敏,手机号等字段会显示为
138****8000。
GET /api/open/v1/guests/{id} — 嘉宾详情
权限:open:guest:read
路径参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| id | int | 嘉宾 ID |
响应示例:
json
{
"code": 200,
"message": "success",
"data": {
"id": 1001,
"name": "张三",
"gender": "male",
"age": 28,
"phone": "13800138000",
"workplace": "上海",
"height": 178,
"weight": 72,
"education": "本科",
"occupation": "软件工程师",
"income_level": "20-50万",
"marital_status": "未婚",
"has_children": "no",
"has_house": "yes",
"has_car": "yes",
"self_intro": "性格开朗,喜欢旅行和运动...",
"requirement": "希望对方年龄在25-30之间...",
"requirement_tags": {
"age_min": 25,
"age_max": 30,
"height_min": 160,
"education_min": 2,
"locations": ["上海"]
},
"photos": [
"https://oss.ailian.com/guest/1001_1.jpg",
"https://oss.ailian.com/guest/1001_2.jpg"
],
"company_id": 5,
"matchmaker_id": 12,
"status": "available",
"created_at": "2025-06-15 10:30:00",
"updated_at": "2025-07-20 14:22:00"
}
}POST /api/open/v1/guests — 创建嘉宾
权限:open:guest:write
请求体:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| name | string | 是 | 姓名,2-20 字符 |
| gender | string | 是 | 性别:male / female |
| age | int | 是 | 年龄,18-80 |
| phone | string | 是 | 手机号,11 位 |
| workplace | string | 是 | 工作地 |
| height | int | 否 | 身高(cm) |
| weight | int | 否 | 体重(kg) |
| education | string | 否 | 学历:高中及以下 / 大专 / 本科 / 硕士 / 博士 |
| occupation | string | 否 | 职业 |
| income_level | string | 否 | 收入水平:10万以下 / 10-20万 / 20-50万 / 50万以上 |
| marital_status | string | 否 | 婚姻状况:未婚 / 离异 / 丧偶 |
| has_children | string | 否 | 子女情况:yes / no |
| has_house | string | 否 | 住房情况:yes / no |
| has_car | string | 否 | 车辆情况:yes / no |
| self_intro | string | 否 | 自我介绍,最长 500 字 |
| requirement | string | 否 | 择偶要求文本描述,最长 500 字 |
| requirement_tags | object | 否 | 结构化择偶标签(JSON 对象,详见下方说明) |
| req_age_min | int | 否 | 择偶年龄要求下限 |
| req_age_max | int | 否 | 择偶年龄要求上限 |
| req_height_min | int | 否 | 择偶身高下限(cm) |
| req_education_min | int | 否 | 最低学历(1=高中及以下, 2=大专, 3=本科, 4=硕士, 5=博士) |
| req_weight_min | int | 否 | 体重下限(kg) |
| req_weight_max | int | 否 | 体重上限(kg) |
| req_income | string | 否 | 收入要求 |
| req_location | string | 否 | 地区要求 |
| req_housing | string | 否 | 婚房要求 |
| req_health | string | 否 | 健康状况要求 |
| photos | string[] | 否 | 照片 URL 数组,最多 9 张 |
| company_id | int | 否 | 所属公司 ID |
| matchmaker_id | int | 否 | 负责红娘 ID |
requirement_tags说明:结构化择偶标签,传入后系统会自动同步到对应的预计算列(req_age_min等)。若同时传入了requirement_tags和预计算列字段,预计算列以手动传入的值为准。
requirement_tags 完整结构:
json
{
"age_min": 25,
"age_max": 35,
"height_min": 170,
"height_max": null,
"weight_min": 60,
"weight_max": 80,
"income_min": 3,
"income_max": null,
"education_min": 3,
"marriage_status": [1],
"has_children": 0,
"has_car": null,
"has_house": null,
"locations": ["重庆", "四川"],
"health": ["健康"],
"other": "三观正,情绪稳定"
}| key | 类型 | 说明 |
|---|---|---|
| age_min | int/null | 年龄要求下限 |
| age_max | int/null | 年龄要求上限 |
| height_min | int/null | 身高下限(cm) |
| height_max | int/null | 身高上限(cm) |
| weight_min | int/null | 体重下限(kg) |
| weight_max | int/null | 体重上限(kg) |
| income_min | int/null | 收入等级下限 |
| income_max | int/null | 收入等级上限 |
| education_min | int/null | 最低学历(1-5) |
| marriage_status | int[]/null | 可接受婚史(1=未婚, 2=离异, 3=丧偶) |
| has_children | int/null | 子女要求(0=否, 1=是, null=不限) |
| has_car | int/null | 车辆要求(0=无, 1=有, null=不限) |
| has_house | int/null | 住房要求(0=无, 1=有, null=不限) |
| locations | string[]/null | 地区要求列表 |
| health | string[]/null | 健康状况要求列表 |
| other | string | 其他补充要求 |
请求示例:
json
{
"name": "李四",
"gender": "female",
"age": 25,
"phone": "13900139000",
"workplace": "北京",
"height": 165,
"weight": 50,
"education": "硕士",
"occupation": "产品经理",
"income_level": "20-50万",
"marital_status": "未婚",
"self_intro": "热爱生活,喜欢阅读",
"requirement": "希望对方年龄在25-35之间,身高170以上",
"requirement_tags": {
"age_min": 25,
"age_max": 35,
"height_min": 170,
"education_min": 3,
"locations": ["北京", "上海"]
},
"company_id": 3
}响应示例:
json
{
"code": 200,
"message": "创建成功",
"data": {
"id": 1002,
"name": "李四",
"gender": "female",
"age": 25,
"requirement": "希望对方年龄在25-35之间,身高170以上",
"requirement_tags": {
"age_min": 25,
"age_max": 35,
"height_min": 170,
"education_min": 3,
"locations": ["北京", "上海"]
},
"status": "incomplete",
"created_at": "2025-08-05 10:00:00"
}
}PUT /api/open/v1/guests/{id} — 更新嘉宾
权限:open:guest:write
路径参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| id | int | 嘉宾 ID |
请求体:与创建接口一致,所有字段均为可选,仅传入需要更新的字段。
响应示例:
json
{
"code": 200,
"message": "更新成功",
"data": {
"id": 1002,
"updated_at": "2025-08-05 11:30:00"
}
}POST /api/open/v1/guests/batch — 批量创建嘉宾
权限:open:guest:write
请求体:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| guests | array | 是 | 嘉宾对象数组,上限 50 条/次 |
请求示例:
json
{
"guests": [
{
"name": "王五",
"gender": "male",
"age": 30,
"phone": "13700137000",
"workplace": "广州"
},
{
"name": "赵六",
"gender": "female",
"age": 26,
"phone": "13600136000",
"workplace": "深圳"
}
]
}响应示例:
json
{
"code": 200,
"message": "批量创建完成",
"data": {
"success_count": 2,
"failed_count": 0,
"results": [
{"index": 0, "status": "success", "id": 1003},
{"index": 1, "status": "success", "id": 1004}
]
}
}注意:批量接口中单条失败不影响其他条目,
results中会标注每条的成功/失败状态及原因。
PUT /api/open/v1/guests/batch — 批量更新嘉宾
权限:open:guest:write
请求体:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| guests | array | 是 | 嘉宾对象数组,每个对象必须包含 id 字段,上限 50 条/次 |
请求示例:
json
{
"guests": [
{"id": 1003, "city": "北京"},
{"id": 1004, "status": 0}
]
}响应示例:
json
{
"code": 200,
"message": "批量更新完成",
"data": {
"success_count": 2,
"failed_count": 0,
"results": [
{"index": 0, "status": "success", "id": 1003},
{"index": 1, "status": "success", "id": 1004}
]
}
}POST /api/open/v1/guests/parse-card — 解析嘉宾卡片
权限:open:guest:read
功能:上传嘉宾卡片图片,AI/OCR 解析为结构化数据(仅解析,不创建嘉宾)。用于预览解析结果,确认后再调用 create-from-card 创建嘉宾。
请求:multipart/form-data
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| file | File | 是 | 嘉宾卡片图片(JPG/PNG,≤10MB) |
| matchmaker_id | int | 否 | 红娘 ID,用于图片查重 |
响应示例:
json
{
"code": 200,
"message": "success",
"data": {
"duplicate": false,
"image_hash": "a1b2c3d4e5f6",
"method": "ai",
"parsed": {
"name": "张三",
"gender": "male",
"age": 28,
"height": 175,
"education": "本科",
"occupation": "工程师",
"selfIntro": "性格开朗...",
"requirement": "希望对方...",
"requirementTags": {
"age_min": 25,
"age_max": 32,
"height_min": 160
}
},
"confidence": "high"
}
}
method说明:ai表示 AI 视觉识别成功,ocr表示降级到 OCR 识别。
duplicate说明:若matchmaker_id已传入且该红娘下已存在相同图片(按image_hash比对),则返回duplicate: true并附带existing_guest信息。
POST /api/open/v1/guests/create-from-card — 通过卡片创建嘉宾(异步)
权限:open:guest:write
功能:上传嘉宾卡片图片,后台异步解析并自动创建嘉宾记录。解析失败(无法识别姓名/性别)时不创建记录。
请求:multipart/form-data
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| file | File | 是 | 嘉宾卡片图片(JPG/PNG,≤10MB) |
| company_id | int | 是 | 所属公司 ID |
| matchmaker_id | int | 否 | 红娘 ID(用于查重) |
| overrides | string | 否 | JSON 字符串,用于覆盖/补充解析结果中的字段 |
响应示例(提交成功,立即返回任务 ID):
json
{
"code": 200,
"message": "success",
"data": {
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "pending",
"async": true,
"message": "任务已提交,请通过 Webhook 或轮询查询结果"
}
}响应示例(图片重复):
json
{
"code": 200,
"message": "success",
"data": {
"duplicate": true,
"existing_guest": {"id": 1001, "name": "张三"},
"message": "该图片已导入过,对应嘉宾:张三"
}
}异步流程:
- 上传图片 → 立即返回
task_id - 后台异步解析图片(AI 优先,降级 OCR)
- 解析成功(识别到姓名+性别)→ 自动创建嘉宾,同步预计算列,计算资料完整度
- 解析失败(无法识别姓名/性别)→ 不创建嘉宾,任务状态为
failed - 创建成功后通过 Webhook 通知:
guest.card_created
overrides 用法示例:
json
{
"name": "张三丰",
"phone": "13800138000",
"company_id": 5
}传入
overrides后,解析结果中的同名字段会被覆盖,缺失字段会被补充。
GET /api/open/v1/guests/card-task/{task_id} — 查询卡片任务状态
权限:open:guest:read
功能:轮询异步卡片创建任务的状态和结果。
路径参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| task_id | string | 任务 ID(由 create-from-card 接口返回) |
响应示例(任务进行中):
json
{
"code": 200,
"message": "success",
"data": {
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "processing",
"created_at": "2025-08-06T14:30:00",
"completed_at": null
}
}响应示例(任务完成):
json
{
"code": 200,
"message": "success",
"data": {
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "done",
"created_at": "2025-08-06T14:30:00",
"completed_at": "2025-08-06T14:30:15",
"result": {
"method": "ai",
"summary": "嘉宾 1002 已创建",
"completeness": 0.75,
"saved": true
}
}
}响应示例(任务失败):
json
{
"code": 200,
"message": "success",
"data": {
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "failed",
"created_at": "2025-08-06T14:30:00",
"completed_at": "2025-08-06T14:30:10",
"error": "图片无法识别,未找到姓名和性别信息"
}
}任务状态枚举:
| 状态 | 说明 |
|---|---|
pending | 等待处理 |
processing | 正在解析 |
done | 解析完成,嘉宾已创建 |
failed | 解析失败或无法识别 |