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-30万",
"income_amount": 250000,
"family_income_amount": 350000,
"family_income_level": "30-50万",
"req_income_amount": 200000,
"req_income_text": "年收入20万以上",
"marital_status": "未婚",
"requirement": "希望对方年龄在25-30之间...",
"requirement_tags": {
"age_min": 25,
"age_max": 30,
"height_min": 160
},
"photos": ["https://oss.ailian.com/guest/1001.jpg"],
"photo_time": "2025-06-10 15:00:00",
"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-30万",
"income_amount": 250000,
"family_income_amount": 350000,
"family_income_level": "30-50万",
"req_income_amount": 200000,
"req_income_text": "年收入20万以上",
"req_location": "上海、江苏",
"req_location_codes": ["310000", "320000"],
"native_place": "陕西省汉中市汉台区",
"native_place_code": "610702",
"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"
],
"photo_time": "2025-06-10 15:00:00",
"company_id": 5,
"matchmaker_id": 12,
"source_id": "CAMP001",
"source": "线下活动",
"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 | 是 | 姓名,1-20 字符 |
| gender | string | 是 | 性别:male / female |
| company_id | int | 是 | 所属公司 ID |
| 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-30万 / 30-50万 / 50-100万 / 100万以上 |
| income_amount | int | 否 | 本人年收入金额(元),权威字段;与 income_level 二选一或同时传入时以金额为准 |
| family_income_amount | int | 否 | 家庭年收入金额(元),为空时等于 income_amount |
| 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_amount | int | 否 | 择偶收入要求下界(元),权威字段 |
| req_income_text | string | 否 | 择偶收入要求原文(如"年收入20万以上"),仅传文本时系统自动解析回填金额 |
| req_location | string | 否 | 地区要求(如"湖南、江西"),系统自动推导行政区划编码列表 req_location_codes |
| req_housing | string | 否 | 婚房要求 |
| req_health | string | 否 | 健康状况要求 |
| native_place | string | 否 | 籍贯/地区(如"陕西省汉中市汉台区"),系统自动推导行政区划编码 native_place_code |
| photos | string[] | 否 | 照片 URL 数组,最多 9 张 |
| photo_time | string | 否 | 图片时间(照片拍摄/生成时间),格式 YYYY-MM-DD HH:MM:SS,不传则默认为创建时间 |
| string | 否 | 微信号 | |
| birth_date | string | 否 | 出生日期 |
| personality | string | 否 | 个性特征 |
| source_id | string | 否 | 来源 ID,最长 150 字符 |
| source | string | 否 | 来源,最长 150 字符 |
| 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-30万",
"income_amount": 250000,
"family_income_amount": 350000,
"req_income_amount": 200000,
"req_income_text": "年收入20万以上",
"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,
"source": "地推"
}响应示例:
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 条/次 |
对象字段与「更新嘉宾」一致,但不支持
ethnicity、hobbies、family_members、health_status、dating_description、accept_flash_marriage;地区字段native_place、req_location传入文本后,系统会自动推导native_place_code、req_location_codes。
请求示例:
json
{
"guests": [
{"id": 1003, "workplace": "北京", "native_place": "湖南长沙"},
{"id": 1004, "status": "available"}
]
}响应示例:
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": "工程师",
"incomeAmount": 250000,
"reqIncomeAmount": 200000,
"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) |
| matchmaker_id | int | 是 | 红娘 ID(必填,用于查重) |
| company_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,
"photo_time": "2025-06-10 15:00:00"
}传入
overrides后,解析结果中的同名字段会被覆盖,缺失字段会被补充。photo_time用于指定图片的拍摄/生成时间,不传则默认为嘉宾创建时间。
查询卡片任务状态
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 | 解析失败或无法识别 |