15 KiB
15 KiB
Banban 统一数据与接口设计文档(Mini Program + talkingq-url,V3)
1. 目标与边界
本设计用于统一 mini-program 与 talkingq-url 的数据库模型与接口语义,目标是:
- 两个服务使用同一套设备身份(
device_id)。 - 保留
talkingq-url/mysql/init/01-init.sql现有表结构不变。 - 在不改动基础表的前提下,补齐家长/小孩/绑定/聊天/定位能力。
硬性边界:
01-init.sql中现有表不改表名、不改字段、不改约束。- 所有新增表仅做增量扩展。
- 新增表字段命名风格对齐现有风格:
snake_case、*_id、is_active、status、created_at、updated_at。
2. 现有冻结表(来自 01-init.sql)
以下表为设备能力基础层,保持不变:
device_auth:设备身份白名单(device_id + serial_number)。device_configs:设备角色与基础配置(含volume)。conversation_histories:设备与角色会话头。conversation_messages:设备与角色会话消息。roles/role_languages:角色与多语言配置。device_firmware_update:设备固件升级状态。system_config:系统配置项。
职责说明:
conversation_histories/conversation_messages继续只服务“设备 <-> AI 角色”的对话,不承担家长-小孩 IM。- 设备鉴权统一走
device_auth,device_id为全局设备业务标识。
3. 新增主体模型
3.1 家长主体表 parents
建议字段:
user_idBIGINT UNSIGNED PK AUTO_INCREMENTopenidVARCHAR(64) UNIQUE NOT NULLunionidVARCHAR(64) NULLnicknameVARCHAR(64) NULLavatar_urlVARCHAR(255) NULLphoneVARCHAR(20) NULLstatusTINYINT NOT NULL DEFAULT 1created_atDATETIME NOT NULL DEFAULT CURRENT_TIMESTAMPupdated_atDATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
索引建议:
uk_openid(openid)idx_unionid(unionid)idx_phone(phone)
3.2 小孩主体表 children
建议字段:
child_idBIGINT UNSIGNED PK AUTO_INCREMENTchild_nameVARCHAR(32) NOT NULLchild_genderTINYINT NOT NULL DEFAULT 2child_birthdayDATE NULLstatusTINYINT NOT NULL DEFAULT 1created_atDATETIME NOT NULL DEFAULT CURRENT_TIMESTAMPupdated_atDATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
说明:
- 不在库内存储
child_age计算列,年龄由查询层按时间实时计算,避免跨年缓存误差。
3.3 家长-小孩关系表 parent_child_relations
建议字段:
idBIGINT UNSIGNED PK AUTO_INCREMENTuser_idBIGINT UNSIGNED NOT NULLchild_idBIGINT UNSIGNED NOT NULLrelation_typeTINYINT NOT NULL DEFAULT 9is_primaryTINYINT(1) NOT NULL DEFAULT 0statusTINYINT NOT NULL DEFAULT 1created_atDATETIME NOT NULL DEFAULT CURRENT_TIMESTAMPupdated_atDATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
约束建议:
UNIQUE(user_id, child_id)FOREIGN KEY (user_id) REFERENCES parents(user_id)FOREIGN KEY (child_id) REFERENCES children(child_id)
3.4 设备归属表 device_bindings
用途:表达“当前哪块设备绑定到哪个小孩”,并与 device_auth 对齐。
建议字段:
idBIGINT UNSIGNED PK AUTO_INCREMENTdevice_idVARCHAR(64) NOT NULLchild_idBIGINT UNSIGNED NOT NULLstatusTINYINT NOT NULL DEFAULT 1bound_atDATETIME NOT NULLunbound_atDATETIME NULLcreated_atDATETIME NOT NULL DEFAULT CURRENT_TIMESTAMPupdated_atDATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
约束建议:
UNIQUE(device_id)UNIQUE(child_id)FOREIGN KEY (device_id) REFERENCES device_auth(device_id)FOREIGN KEY (child_id) REFERENCES children(child_id)
3.5 绑定会话表 device_bind_sessions
建议字段:
idBIGINT UNSIGNED PK AUTO_INCREMENTbind_tokenCHAR(36) UNIQUE NOT NULLdevice_idVARCHAR(64) NOT NULLinitiator_user_idBIGINT UNSIGNED NOT NULLtarget_child_idBIGINT UNSIGNED NULLchallenge_code_hashCHAR(64) NULLchallenge_set_atDATETIME NULLexpires_atDATETIME NOT NULLmax_attempt_countTINYINT UNSIGNED NOT NULL DEFAULT 5attempt_countTINYINT UNSIGNED NOT NULL DEFAULT 0statusTINYINT NOT NULL DEFAULT 1confirmed_atDATETIME NULLconsumed_atDATETIME NULLcreated_atDATETIME NOT NULL DEFAULT CURRENT_TIMESTAMPupdated_atDATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
约束建议:
FOREIGN KEY (device_id) REFERENCES device_auth(device_id)FOREIGN KEY (initiator_user_id) REFERENCES parents(user_id)FOREIGN KEY (target_child_id) REFERENCES children(child_id)
3.6 绑定历史表 device_bind_history
建议字段:
idBIGINT UNSIGNED PK AUTO_INCREMENTdevice_idVARCHAR(64) NOT NULLchild_idBIGINT UNSIGNED NOT NULLbound_by_user_idBIGINT UNSIGNED NOT NULLunbound_by_user_idBIGINT UNSIGNED NULLbind_sourceTINYINT NOT NULL DEFAULT 1bound_atDATETIME NOT NULLunbound_atDATETIME NULLunbind_reasonVARCHAR(191) NULLcreated_atDATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
约束建议:
FOREIGN KEY (device_id) REFERENCES device_auth(device_id)FOREIGN KEY (child_id) REFERENCES children(child_id)FOREIGN KEY (bound_by_user_id) REFERENCES parents(user_id)FOREIGN KEY (unbound_by_user_id) REFERENCES parents(user_id)
3.7 卡片表 cards
建议字段:
card_idBIGINT UNSIGNED PK AUTO_INCREMENTcard_uuidVARCHAR(64) UNIQUE NOT NULLdevice_idVARCHAR(64) UNIQUE NULLcard_nameVARCHAR(64) NULLstatusTINYINT NOT NULL DEFAULT 0total_swapsINT NOT NULL DEFAULT 0created_atDATETIME NOT NULL DEFAULT CURRENT_TIMESTAMPupdated_atDATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
约束建议:
FOREIGN KEY (device_id) REFERENCES device_auth(device_id)
3.8 设备设置表 device_settings
建议字段:
setting_idBIGINT UNSIGNED PK AUTO_INCREMENTdevice_idVARCHAR(64) NOT NULL UNIQUEsleep_modeTINYINT NOT NULL DEFAULT 0disable_time_startTIME NULLdisable_time_endTIME NULLtimezoneVARCHAR(32) NOT NULL DEFAULT 'Asia/Shanghai'volumeTINYINT UNSIGNED NULLbrightnessTINYINT UNSIGNED NULLdisable_weekdaysVARCHAR(32) NULLcreated_atDATETIME NOT NULL DEFAULT CURRENT_TIMESTAMPupdated_atDATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
兼容规则:
volume同步写入device_configs.volume,防止两服务读到不同值。- 若只允许单一音量来源,则以
device_configs.volume为准,device_settings.volume可后续下线。 disable_time_start/disable_time_end与历史命名sleep_start/sleep_end一一映射。- 禁用时段按
timezone解释;跨天时段(如 22:00-07:00)按“跨日窗口”处理。
4. 聊天与定位模型(新增,不改 01 现有会话表)
4.1 IM 会话表 im_conversations
用途:仅服务家长-小孩、小孩-小孩 1v1,不与 conversation_histories 混用。
建议字段:
idBIGINT UNSIGNED PK AUTO_INCREMENTconversation_typeTINYINT UNSIGNED NOT NULLparticipant_a_typeTINYINT UNSIGNED NOT NULLparticipant_a_idVARCHAR(64) NOT NULLparticipant_b_typeTINYINT UNSIGNED NOT NULLparticipant_b_idVARCHAR(64) NOT NULLpair_keyVARCHAR(191) NOT NULLstatusTINYINT NOT NULL DEFAULT 1last_seqBIGINT UNSIGNED NOT NULL DEFAULT 0message_countBIGINT UNSIGNED NOT NULL DEFAULT 0last_message_previewVARCHAR(255) NULLlast_message_atDATETIME NULLext_jsonJSON NULLcreated_atDATETIME NOT NULL DEFAULT CURRENT_TIMESTAMPupdated_atDATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
说明:
- 会话核心字段保持通用,不使用
child_low_id/child_high_id这类场景耦合命名。 conversation_type使用类型码,可扩展;新增会话类型优先通过“类型码 + 业务校验 +ext_json”扩展,无需改核心表。- 当前建议启用类型:
1-child_peer、2-parent_child。
约束建议:
UNIQUE(conversation_type, pair_key)INDEX idx_participant_a (participant_a_type, participant_a_id)INDEX idx_participant_b (participant_b_type, participant_b_id)INDEX idx_last_message_at (last_message_at)
4.2 IM 消息表 im_messages
建议字段:
idBIGINT UNSIGNED PK AUTO_INCREMENTconversation_idBIGINT UNSIGNED NOT NULLseqBIGINT UNSIGNED NOT NULLsender_typeTINYINT UNSIGNED NOT NULLsender_idVARCHAR(64) NOT NULLreceiver_typeTINYINT UNSIGNED NOT NULLreceiver_idVARCHAR(64) NOT NULLcontent_typeTINYINT UNSIGNED NOT NULLcontent_textMEDIUMTEXT NULLcontent_jsonJSON NULLmedia_file_keyVARCHAR(255) NULLmedia_duration_msINT UNSIGNED NULLmedia_mime_typeVARCHAR(64) NULLmedia_size_bytesBIGINT UNSIGNED NULLmedia_transcript_textTEXT NULLclient_msg_idVARCHAR(64) NULLsender_name_snapshotVARCHAR(64) NULLsender_avatar_snapshotVARCHAR(255) NULLreceiver_name_snapshotVARCHAR(64) NULLreceiver_avatar_snapshotVARCHAR(255) NULLext_jsonJSON NULLcreated_atDATETIME NOT NULL DEFAULT CURRENT_TIMESTAMPdeleted_atDATETIME NULL
约束建议:
UNIQUE(conversation_id, seq)UNIQUE(conversation_id, client_msg_id)FOREIGN KEY (conversation_id) REFERENCES im_conversations(id) ON DELETE CASCADEINDEX idx_sender (sender_type, sender_id, created_at)INDEX idx_receiver (receiver_type, receiver_id, created_at)
4.2.1 文本与语音消息规则
content_type=1(text):content_text必填。content_type=2(audio):media_file_key必填,建议同时写入media_duration_ms、media_mime_type、media_size_bytes。content_type=3(image):media_file_key必填。content_type=4(json):content_json必填。- 语音转写内容可写入
media_transcript_text,用于检索与展示。 - 展示层优先使用
sender_name_snapshot/sender_avatar_snapshot与receiver_*_snapshot,减少联表查询。
4.3 位置表
child_location_current:
child_idBIGINT UNSIGNED PKdevice_idVARCHAR(64) NOT NULLcoord_typeVARCHAR(16) NOT NULL DEFAULT 'gcj02'latDECIMAL(10,7) NOT NULLlngDECIMAL(10,7) NOT NULLaccuracy_mINT UNSIGNED NULLaltitude_mDECIMAL(8,2) NULLspeed_mpsDECIMAL(8,2) NULLheading_degSMALLINT UNSIGNED NULLsourceTINYINT UNSIGNED NOT NULLbattery_pctTINYINT UNSIGNED NULLdevice_timeDATETIME NOT NULLserver_timeDATETIME NOT NULL DEFAULT CURRENT_TIMESTAMPupdated_atDATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
child_location_history:
idBIGINT UNSIGNED PK AUTO_INCREMENTchild_idBIGINT UNSIGNED NOT NULLdevice_idVARCHAR(64) NOT NULLcoord_typeVARCHAR(16) NOT NULL DEFAULT 'gcj02'- 其余定位字段与
child_location_current对齐 created_atDATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
4.3.1 位置上报协议(统一格式)
- 上报字段:
device_id、child_id、coord_type、lat、lng、accuracy_m、source、device_time、battery_pct。 - 坐标系标准:统一使用
gcj02。 - 坐标格式:统一按
lat,lng(纬度在前,经度在后)传输和存储。 - 若设备侧提供
wgs84,服务端需先转换到gcj02后再入库;原始坐标可选写入ext_json备查。 - 写入规则:同事务写
child_location_history并覆盖child_location_current。
5. 核心业务流程
5.1 设备注册与鉴权
- 生产或后台调用
talkingq-url现有注册接口,写入device_auth。 - 手表请求携带
X-Device-ID与X-Device-Serial。 - 后端基于
device_auth鉴权通过后继续处理聊天/定位/绑定。
5.2 绑定流程(扫码 + 确认码)
- 家长登录后发起
bind/start,创建device_bind_sessions。 - 手表上报确认码,更新会话挑战信息。
- 家长提交确认码。
- 后端校验通过后开启事务。
- upsert
parent_child_relations。 - upsert
device_bindings(保证一设备一行、一小孩一行)。 - 追加
device_bind_history。 - 更新会话状态为
confirmed/consumed并提交事务。
5.3 聊天流程
- 设备 AI 对话仍走
conversation_histories + conversation_messages。 - 家长-小孩、小孩-小孩消息走
im_conversations + im_messages。 - IM 消息统一使用
sender_type/sender_id + receiver_type/receiver_id,不按场景拆专用发送者字段。 - 发送接口必须使用
client_msg_id幂等。 - 查询前必须校验
parent_child_relations权限。 - 列表展示优先读取消息快照字段,降低跨表查询成本。
5.4 位置流程
- 手表上报定位写入
child_location_history。 - 同事务更新
child_location_current。 - 小程序查询当前定位读
child_location_current,轨迹读child_location_history。 - 地址解析使用腾讯位置服务;若解析失败,前端降级展示经纬度。
6. 统一约束与实现规则
- 所有设备引用字段统一使用
device_id VARCHAR(64),不再新增watch_device_id BIGINT。 - 设备主身份只认
device_auth.device_id。 - 跨主体通用 ID 字段统一采用字符串(如
participant_*_id、sender_id、receiver_id)。 - 所有业务表统一包含
created_at/updated_at(历史流水类可无updated_at)。 status用于业务态,is_active用于启停态;两者不混用。- 关键写路径(绑定确认、发消息、位置写入)必须事务化。
- 腾讯位置服务启用前提:必须配置合法
key,并完成域名/来源白名单与配额设置。 - 地图相关接口统一使用
gcj02和lat,lng;禁止混用wgs84/bd09直接入库。
7. 分阶段落地
- 第一阶段:落地
parents/children/parent_child_relations/device_bind_*,打通绑定链路。 - 第二阶段:落地
im_conversations/im_messages,打通家长与小孩 IM。 - 第三阶段:落地
child_location_current/history,打通定位链路。 - 第四阶段:补充审计、告警、实时推送和运营能力。
8. 验收标准
- 不修改
01-init.sql任一现有表,服务可正常启动。 - 设备鉴权、角色配置、OTA能力保持可用。
- 家长可完成扫码绑定、解绑、重绑,且历史保留。
- 家长可查看自己小孩与其他小孩完整双向消息。
- 小程序可查看小孩最新位置与历史轨迹。