Files
banban/mini-program/design.md
HycJack a22fcafea9 新增小程序后端代码,包括数据库、路由、服务层等。
小程序前后端打通,包括登录、注册、绑定设备、查询绑定信息,修改小朋友名称等功能。
2026-04-13 01:54:57 +08:00

15 KiB
Raw Blame History

Banban 统一数据与接口设计文档Mini Program + talkingq-urlV3

1. 目标与边界

本设计用于统一 mini-programtalkingq-url 的数据库模型与接口语义,目标是:

  1. 两个服务使用同一套设备身份(device_id)。
  2. 保留 talkingq-url/mysql/init/01-init.sql 现有表结构不变。
  3. 在不改动基础表的前提下,补齐家长/小孩/绑定/聊天/定位能力。

硬性边界:

  1. 01-init.sql 中现有表不改表名、不改字段、不改约束。
  2. 所有新增表仅做增量扩展。
  3. 新增表字段命名风格对齐现有风格:snake_case*_idis_activestatuscreated_atupdated_at

2. 现有冻结表(来自 01-init.sql

以下表为设备能力基础层,保持不变:

  1. device_auth:设备身份白名单(device_id + serial_number)。
  2. device_configs:设备角色与基础配置(含 volume)。
  3. conversation_histories:设备与角色会话头。
  4. conversation_messages:设备与角色会话消息。
  5. roles / role_languages:角色与多语言配置。
  6. device_firmware_update:设备固件升级状态。
  7. system_config:系统配置项。

职责说明:

  1. conversation_histories/conversation_messages 继续只服务“设备 <-> AI 角色”的对话,不承担家长-小孩 IM。
  2. 设备鉴权统一走 device_authdevice_id 为全局设备业务标识。

3. 新增主体模型

3.1 家长主体表 parents

建议字段:

  1. user_id BIGINT UNSIGNED PK AUTO_INCREMENT
  2. openid VARCHAR(64) UNIQUE NOT NULL
  3. unionid VARCHAR(64) NULL
  4. nickname VARCHAR(64) NULL
  5. avatar_url VARCHAR(255) NULL
  6. phone VARCHAR(20) NULL
  7. status TINYINT NOT NULL DEFAULT 1
  8. created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
  9. updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

索引建议:

  1. uk_openid(openid)
  2. idx_unionid(unionid)
  3. idx_phone(phone)

3.2 小孩主体表 children

建议字段:

  1. child_id BIGINT UNSIGNED PK AUTO_INCREMENT
  2. child_name VARCHAR(32) NOT NULL
  3. child_gender TINYINT NOT NULL DEFAULT 2
  4. child_birthday DATE NULL
  5. status TINYINT NOT NULL DEFAULT 1
  6. created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
  7. updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

说明:

  1. 不在库内存储 child_age 计算列,年龄由查询层按时间实时计算,避免跨年缓存误差。

3.3 家长-小孩关系表 parent_child_relations

建议字段:

  1. id BIGINT UNSIGNED PK AUTO_INCREMENT
  2. user_id BIGINT UNSIGNED NOT NULL
  3. child_id BIGINT UNSIGNED NOT NULL
  4. relation_type TINYINT NOT NULL DEFAULT 9
  5. is_primary TINYINT(1) NOT NULL DEFAULT 0
  6. status TINYINT NOT NULL DEFAULT 1
  7. created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
  8. updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

约束建议:

  1. UNIQUE(user_id, child_id)
  2. FOREIGN KEY (user_id) REFERENCES parents(user_id)
  3. FOREIGN KEY (child_id) REFERENCES children(child_id)

3.4 设备归属表 device_bindings

用途:表达“当前哪块设备绑定到哪个小孩”,并与 device_auth 对齐。

建议字段:

  1. id BIGINT UNSIGNED PK AUTO_INCREMENT
  2. device_id VARCHAR(64) NOT NULL
  3. child_id BIGINT UNSIGNED NOT NULL
  4. status TINYINT NOT NULL DEFAULT 1
  5. bound_at DATETIME NOT NULL
  6. unbound_at DATETIME NULL
  7. created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
  8. updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

约束建议:

  1. UNIQUE(device_id)
  2. UNIQUE(child_id)
  3. FOREIGN KEY (device_id) REFERENCES device_auth(device_id)
  4. FOREIGN KEY (child_id) REFERENCES children(child_id)

3.5 绑定会话表 device_bind_sessions

建议字段:

  1. id BIGINT UNSIGNED PK AUTO_INCREMENT
  2. bind_token CHAR(36) UNIQUE NOT NULL
  3. device_id VARCHAR(64) NOT NULL
  4. initiator_user_id BIGINT UNSIGNED NOT NULL
  5. target_child_id BIGINT UNSIGNED NULL
  6. challenge_code_hash CHAR(64) NULL
  7. challenge_set_at DATETIME NULL
  8. expires_at DATETIME NOT NULL
  9. max_attempt_count TINYINT UNSIGNED NOT NULL DEFAULT 5
  10. attempt_count TINYINT UNSIGNED NOT NULL DEFAULT 0
  11. status TINYINT NOT NULL DEFAULT 1
  12. confirmed_at DATETIME NULL
  13. consumed_at DATETIME NULL
  14. created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
  15. updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

约束建议:

  1. FOREIGN KEY (device_id) REFERENCES device_auth(device_id)
  2. FOREIGN KEY (initiator_user_id) REFERENCES parents(user_id)
  3. FOREIGN KEY (target_child_id) REFERENCES children(child_id)

3.6 绑定历史表 device_bind_history

建议字段:

  1. id BIGINT UNSIGNED PK AUTO_INCREMENT
  2. device_id VARCHAR(64) NOT NULL
  3. child_id BIGINT UNSIGNED NOT NULL
  4. bound_by_user_id BIGINT UNSIGNED NOT NULL
  5. unbound_by_user_id BIGINT UNSIGNED NULL
  6. bind_source TINYINT NOT NULL DEFAULT 1
  7. bound_at DATETIME NOT NULL
  8. unbound_at DATETIME NULL
  9. unbind_reason VARCHAR(191) NULL
  10. created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP

约束建议:

  1. FOREIGN KEY (device_id) REFERENCES device_auth(device_id)
  2. FOREIGN KEY (child_id) REFERENCES children(child_id)
  3. FOREIGN KEY (bound_by_user_id) REFERENCES parents(user_id)
  4. FOREIGN KEY (unbound_by_user_id) REFERENCES parents(user_id)

3.7 卡片表 cards

建议字段:

  1. card_id BIGINT UNSIGNED PK AUTO_INCREMENT
  2. card_uuid VARCHAR(64) UNIQUE NOT NULL
  3. device_id VARCHAR(64) UNIQUE NULL
  4. card_name VARCHAR(64) NULL
  5. status TINYINT NOT NULL DEFAULT 0
  6. total_swaps INT NOT NULL DEFAULT 0
  7. created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
  8. updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

约束建议:

  1. FOREIGN KEY (device_id) REFERENCES device_auth(device_id)

3.8 设备设置表 device_settings

建议字段:

  1. setting_id BIGINT UNSIGNED PK AUTO_INCREMENT
  2. device_id VARCHAR(64) NOT NULL UNIQUE
  3. sleep_mode TINYINT NOT NULL DEFAULT 0
  4. disable_time_start TIME NULL
  5. disable_time_end TIME NULL
  6. timezone VARCHAR(32) NOT NULL DEFAULT 'Asia/Shanghai'
  7. volume TINYINT UNSIGNED NULL
  8. brightness TINYINT UNSIGNED NULL
  9. disable_weekdays VARCHAR(32) NULL
  10. created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
  11. updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

兼容规则:

  1. volume 同步写入 device_configs.volume,防止两服务读到不同值。
  2. 若只允许单一音量来源,则以 device_configs.volume 为准,device_settings.volume 可后续下线。
  3. disable_time_start/disable_time_end 与历史命名 sleep_start/sleep_end 一一映射。
  4. 禁用时段按 timezone 解释;跨天时段(如 22:00-07:00按“跨日窗口”处理。

4. 聊天与定位模型(新增,不改 01 现有会话表)

4.1 IM 会话表 im_conversations

用途:仅服务家长-小孩、小孩-小孩 1v1不与 conversation_histories 混用。

建议字段:

  1. id BIGINT UNSIGNED PK AUTO_INCREMENT
  2. conversation_type TINYINT UNSIGNED NOT NULL
  3. participant_a_type TINYINT UNSIGNED NOT NULL
  4. participant_a_id VARCHAR(64) NOT NULL
  5. participant_b_type TINYINT UNSIGNED NOT NULL
  6. participant_b_id VARCHAR(64) NOT NULL
  7. pair_key VARCHAR(191) NOT NULL
  8. status TINYINT NOT NULL DEFAULT 1
  9. last_seq BIGINT UNSIGNED NOT NULL DEFAULT 0
  10. message_count BIGINT UNSIGNED NOT NULL DEFAULT 0
  11. last_message_preview VARCHAR(255) NULL
  12. last_message_at DATETIME NULL
  13. ext_json JSON NULL
  14. created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
  15. updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

说明:

  1. 会话核心字段保持通用,不使用 child_low_id/child_high_id 这类场景耦合命名。
  2. conversation_type 使用类型码,可扩展;新增会话类型优先通过“类型码 + 业务校验 + ext_json”扩展,无需改核心表。
  3. 当前建议启用类型:1-child_peer2-parent_child

约束建议:

  1. UNIQUE(conversation_type, pair_key)
  2. INDEX idx_participant_a (participant_a_type, participant_a_id)
  3. INDEX idx_participant_b (participant_b_type, participant_b_id)
  4. INDEX idx_last_message_at (last_message_at)

4.2 IM 消息表 im_messages

建议字段:

  1. id BIGINT UNSIGNED PK AUTO_INCREMENT
  2. conversation_id BIGINT UNSIGNED NOT NULL
  3. seq BIGINT UNSIGNED NOT NULL
  4. sender_type TINYINT UNSIGNED NOT NULL
  5. sender_id VARCHAR(64) NOT NULL
  6. receiver_type TINYINT UNSIGNED NOT NULL
  7. receiver_id VARCHAR(64) NOT NULL
  8. content_type TINYINT UNSIGNED NOT NULL
  9. content_text MEDIUMTEXT NULL
  10. content_json JSON NULL
  11. media_file_key VARCHAR(255) NULL
  12. media_duration_ms INT UNSIGNED NULL
  13. media_mime_type VARCHAR(64) NULL
  14. media_size_bytes BIGINT UNSIGNED NULL
  15. media_transcript_text TEXT NULL
  16. client_msg_id VARCHAR(64) NULL
  17. sender_name_snapshot VARCHAR(64) NULL
  18. sender_avatar_snapshot VARCHAR(255) NULL
  19. receiver_name_snapshot VARCHAR(64) NULL
  20. receiver_avatar_snapshot VARCHAR(255) NULL
  21. ext_json JSON NULL
  22. created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
  23. deleted_at DATETIME NULL

约束建议:

  1. UNIQUE(conversation_id, seq)
  2. UNIQUE(conversation_id, client_msg_id)
  3. FOREIGN KEY (conversation_id) REFERENCES im_conversations(id) ON DELETE CASCADE
  4. INDEX idx_sender (sender_type, sender_id, created_at)
  5. INDEX idx_receiver (receiver_type, receiver_id, created_at)

4.2.1 文本与语音消息规则

  1. content_type=1(text)content_text 必填。
  2. content_type=2(audio)media_file_key 必填,建议同时写入 media_duration_msmedia_mime_typemedia_size_bytes
  3. content_type=3(image)media_file_key 必填。
  4. content_type=4(json)content_json 必填。
  5. 语音转写内容可写入 media_transcript_text,用于检索与展示。
  6. 展示层优先使用 sender_name_snapshot/sender_avatar_snapshotreceiver_*_snapshot,减少联表查询。

4.3 位置表

child_location_current

  1. child_id BIGINT UNSIGNED PK
  2. device_id VARCHAR(64) NOT NULL
  3. coord_type VARCHAR(16) NOT NULL DEFAULT 'gcj02'
  4. lat DECIMAL(10,7) NOT NULL
  5. lng DECIMAL(10,7) NOT NULL
  6. accuracy_m INT UNSIGNED NULL
  7. altitude_m DECIMAL(8,2) NULL
  8. speed_mps DECIMAL(8,2) NULL
  9. heading_deg SMALLINT UNSIGNED NULL
  10. source TINYINT UNSIGNED NOT NULL
  11. battery_pct TINYINT UNSIGNED NULL
  12. device_time DATETIME NOT NULL
  13. server_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
  14. updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

child_location_history

  1. id BIGINT UNSIGNED PK AUTO_INCREMENT
  2. child_id BIGINT UNSIGNED NOT NULL
  3. device_id VARCHAR(64) NOT NULL
  4. coord_type VARCHAR(16) NOT NULL DEFAULT 'gcj02'
  5. 其余定位字段与 child_location_current 对齐
  6. created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP

4.3.1 位置上报协议(统一格式)

  1. 上报字段:device_idchild_idcoord_typelatlngaccuracy_msourcedevice_timebattery_pct
  2. 坐标系标准:统一使用 gcj02
  3. 坐标格式:统一按 lat,lng(纬度在前,经度在后)传输和存储。
  4. 若设备侧提供 wgs84,服务端需先转换到 gcj02 后再入库;原始坐标可选写入 ext_json 备查。
  5. 写入规则:同事务写 child_location_history 并覆盖 child_location_current

5. 核心业务流程

5.1 设备注册与鉴权

  1. 生产或后台调用 talkingq-url 现有注册接口,写入 device_auth
  2. 手表请求携带 X-Device-IDX-Device-Serial
  3. 后端基于 device_auth 鉴权通过后继续处理聊天/定位/绑定。

5.2 绑定流程(扫码 + 确认码)

  1. 家长登录后发起 bind/start,创建 device_bind_sessions
  2. 手表上报确认码,更新会话挑战信息。
  3. 家长提交确认码。
  4. 后端校验通过后开启事务。
  5. upsert parent_child_relations
  6. upsert device_bindings(保证一设备一行、一小孩一行)。
  7. 追加 device_bind_history
  8. 更新会话状态为 confirmed/consumed 并提交事务。

5.3 聊天流程

  1. 设备 AI 对话仍走 conversation_histories + conversation_messages
  2. 家长-小孩、小孩-小孩消息走 im_conversations + im_messages
  3. IM 消息统一使用 sender_type/sender_id + receiver_type/receiver_id,不按场景拆专用发送者字段。
  4. 发送接口必须使用 client_msg_id 幂等。
  5. 查询前必须校验 parent_child_relations 权限。
  6. 列表展示优先读取消息快照字段,降低跨表查询成本。

5.4 位置流程

  1. 手表上报定位写入 child_location_history
  2. 同事务更新 child_location_current
  3. 小程序查询当前定位读 child_location_current,轨迹读 child_location_history
  4. 地址解析使用腾讯位置服务;若解析失败,前端降级展示经纬度。

6. 统一约束与实现规则

  1. 所有设备引用字段统一使用 device_id VARCHAR(64),不再新增 watch_device_id BIGINT
  2. 设备主身份只认 device_auth.device_id
  3. 跨主体通用 ID 字段统一采用字符串(如 participant_*_idsender_idreceiver_id)。
  4. 所有业务表统一包含 created_at/updated_at(历史流水类可无 updated_at)。
  5. status 用于业务态,is_active 用于启停态;两者不混用。
  6. 关键写路径(绑定确认、发消息、位置写入)必须事务化。
  7. 腾讯位置服务启用前提:必须配置合法 key,并完成域名/来源白名单与配额设置。
  8. 地图相关接口统一使用 gcj02lat,lng;禁止混用 wgs84/bd09 直接入库。

7. 分阶段落地

  1. 第一阶段:落地 parents/children/parent_child_relations/device_bind_*,打通绑定链路。
  2. 第二阶段:落地 im_conversations/im_messages,打通家长与小孩 IM。
  3. 第三阶段:落地 child_location_current/history,打通定位链路。
  4. 第四阶段:补充审计、告警、实时推送和运营能力。

8. 验收标准

  1. 不修改 01-init.sql 任一现有表,服务可正常启动。
  2. 设备鉴权、角色配置、OTA能力保持可用。
  3. 家长可完成扫码绑定、解绑、重绑,且历史保留。
  4. 家长可查看自己小孩与其他小孩完整双向消息。
  5. 小程序可查看小孩最新位置与历史轨迹。