验证状态:已源码核验、未联调(无 app 调用图);本页为流程编排页,不复制正本字段表,各步骤的协议契约、完成判据与错误出口以其链接的正本页为准(核验基线同各正本页:源码归纳 @ 2026-09-14)。

分享设备

串起设备分享全生命周期的状态机:发起(To be confirm share)→ 确认(confirm share),退场走发起方撤销(cancel share)或受赠方解除(lift share)。分享是投影复制而非共同所有:发起方保留自己的设备直接拥有投影,受赠方得到的是设备分享投影——不能再次分享,更不能对它解绑(见解绑与解除分享)。

前置条件

  • 双方均已完成注册与登录;受赠方名下必须有用户个人空间租户(否则发起时被 Sharing users have no personal space 拒绝)。
  • 发起方是设备直接拥有者:deviceId 从设备列表 state=bind 条目取得(查询个人空间设备列表(V1 视图)查询个人空间设备列表);分享来的设备不能作为分享源。
  • 服务端无显式「发起方 / 受赠方」角色标志,双方边界由租户隔离与分享记录归属实现(各正本页「错误与边界」节)。

主路径

state 流转一览(分享记录驻发起方租户,分享投影驻受赠方租户,两行同步;流转细节见各正本页):

1发起(share / v1-share):两行置 To be confirm share,记录写 inviteTime
2确认(confirm-share,受赠方):两行置 confirm share,记录写 confirmTime
3撤销(cancel-share,发起方):两行置 cancel share 并软删,记录写 cancelTime(待确认与已确认都可撤)
4解除(lift-share,受赠方):两行置 lift share 并软删,记录写 liftTime
  1. 发起方发起分享:推荐发起设备分享(V1 视图)——联系人三选一(用户名 / 邮箱 / 手机号自动识别)、分享数量上限校验,成功响应 extraData.targetUsername 回显解析后的目标用户名;只传用户名的场景也可用第一代发起设备分享(v1 最终转调同一 service 实现)。
  2. 发起方管理已发出的分享查询设备分享记录列表是「分享管理」页数据源(deviceShareId 是撤销与改标记的定位键;它只返回我发出的分享——收到的分享经设备列表 state=To be confirm share / confirm share 条目感知,v1 列表的 deviceShare / deviceShareList 装配语义见该正本页)。可按需调用修改设备分享管理标记——设备管理标记 (deviceManage) 是表示分享者用户名的非权威标记,省略字段会把标记清空。
  3. 受赠方确认:在设备列表看到 state=To be confirm share 条目后调用确认设备分享。入参 deviceId受赠方自己租户内的分享投影 ID(设备列表该条目的 deviceId),不是发起方的投影 ID、也不是分享记录 ID。
  4. 退场:发起方收回走撤销设备分享(按 deviceShareId,待确认与已确认都可撤销);受赠方退出走解除设备分享(按 deviceId)。撤销与解除即时腾出分享上限名额(上限仅计已确认)。

双角色操作边界

动作 正本页 谁可操作 定位键
发起 发起设备分享(V1 视图) / 发起设备分享 发起方(自有直接拥有投影) deviceId + 联系人
确认 确认设备分享 受赠方(记录按 targetUsername 双重锚定) deviceId(自己租户的分享投影)
撤销 撤销设备分享 发起方(记录驻发起方租户) deviceShareId
解除 解除设备分享 受赠方(记录按 targetUsername 双重锚定) deviceId
查记录 / 改标记 查询设备分享记录列表 / 修改设备分享管理标记 发起方 deviceShareId

错位调用的出口:撤销传他人租户的记录 ID → Device share not exists;确认 / 解除传非本租户投影 → The data collection device does not exist;改管理标记错位 → data=false 不报错。

失败与恢复

  • 联系人三选一识别:服务端只对 targetUsername 字段做形态识别(含 @ 按邮箱、纯数字且 ≥7 位按手机号、其余按用户名),反查顺序为用户名 → 邮箱 → 手机号;Incorrect email / Incorrect phone number 表示反查无绑定记录,三者皆空报参数缺失错误。识别歧义(如含 @ 的合法用户名)由 App 输入约束消化。
  • 分享上限:单台设备的已确认分享达到上限即拒绝(默认 10,走 Nacos 配置 device.share.limit仅统计已确认分享,待确认不占名额,撤销 / 解除即时腾额)。超限 error 为已插值文案 Device share limit reached, maximum N shares allowedextraDatadeviceShareLimit(数值型当前上限)与 message(未插值模板),可据此做本地化提示。上限校验先于重复分享校验执行(见发起设备分享(V1 视图))。
  • 发起校验链其余出口(见两代发起正本页):Unable to share with oneself(不能自分享);The user corresponding to the shared username does not exist(目标用户不存在);Sharing users have no personal space(目标无用户个人空间租户);Device sharing already exists(同一设备对同一目标已有活跃分享——已撤销 / 已解除的记录已软删,可重新发起);The data collection device does not existdeviceId 非本租户直接拥有投影);The data collection device shared with the user already exists(目标租户已有该设备的有效投影)。
  • 确认 / 解除出口The data collection device does not exist——投影已随撤销 / 解除 / 归属转移退场,或 ID 有误。重复确认不会报错而是再次写成功并刷新 confirmTime(源码不校验投影当前 state),App 只应对 To be confirm share 条目展示确认按钮。
  • 并发:确认与发起方撤销并发到达时,终态以服务端事务先后为准;确认成功后设备从列表消失的情况应按「分享已被撤销」兜底提示。
  • 退场联动:发起方解绑自有设备或触发设备归属转移绑定(force / 授权码变化),会使其派生的全部分享投影与分享记录一并退场——受赠方侧表现为设备消失(见绑定设备解绑与解除分享)。
  • 通用出口:认证失败族(HTTP 200 + status=1000,重新登录);Bean Validation 失败走请求校验出口(HTTP 400 / status=1002 族);判定口径见错误响应差异

收尾

  • 任一写操作成功后,双方都应重新拉取各自列表刷新界面;服务端不向对方推送实时通知,「对方已收到 / 已确认」的体验由 App 自建轮询或刷新时机。
  • 分享上限名额与活跃分享状态以重新拉取后的列表为准,不要在客户端维护权威计数。
  • 提醒用户:分享不是共同所有——受赠方不能把分享来的设备再次分享,也不能对它解绑(正确退场是解除分享,见解绑与解除分享)。