验证状态:已源码核验、未联调(无 app 调用图);services 基线:源码归纳 @ 2026-09-14
把当前用户个人空间内的一台自有设备(设备直接拥有投影)分享给另一名用户,是分享生命周期的第一步写端点。App「分享设备」动作(选择联系人并确认)由此发起:服务端在目标用户的个人空间租户创建 To be confirm share 设备分享投影,并在发起方租户写入一条分享记录(device_share)。受赠方确认前设备不出现在其可用列表语义中(state 仍为待确认),确认与后续撤销/解除分别见确认设备分享、撤销设备分享、解除设备分享。
设备分享投影与设备直接拥有投影的边界见账号与个人空间。
| 判定证据 | 内容 |
|---|---|
| 旧 app 文档收录记录 | 旧 app 文档仓在 docs/api/main-api/device/data-acquisition-device/shareForPersonalSpace/ 收录本端点,属 App 既有调用面 |
| 两代分工语义 | /v1/retail 第二代的 V1 发起设备分享 最终转调本端点同一 service 实现(联系人三选一与分享上限是 v1 增强项);撤销/确认/解除只有第一代端点,发起与生命周期写路径以第一代为共同底层 |
| 后端持续维护迹象 | 分享主链路由契约测试钉住,第一代 2026-09 仍有维护提交 |
POST /main-service/main-api/device/data-acquisition-device/shareForPersonalSpace — 把当前用户个人空间内的一台自有设备(设备直接拥有投影)分享给另一名用户,是分享生命周期的第一步写端点。
端点全量事实(参数、请求/响应字段、错误码、权限点)见清单层 device · data-acquisition-device 采集设备;业务语义(wire 惯例、限频、租户声明等)见设备业务 · data-acquisition-device 采集设备。
前三步在 controller,后两步在 service;任一步失败即中止:
targetUsername 等于当前登录用户名 → Unable to share with oneself。The user corresponding to the shared username does not exist。tenantType=personal-space 的租户 → Sharing users have no personal space。deviceId 对同一 targetUsername 已存在活跃分享记录(软删行不计)→ Device sharing already exists。deviceId 在发起方租户无有效投影 → The data collection device does not exist;目标租户已有该设备的有效投影 → The data collection device shared with the user already exists(重复投影守卫)。status=200 且 data=true 表示发起完成。受赠方此后在其设备列表(查询个人空间设备列表)可见 state=To be confirm share 的分享投影;发起方在设备分享记录列表可见该条记录(inviteTime 已写、confirmTime 为空)。
业务失败均为业务拒绝族,error 为异常消息原文(判定口径见错误响应差异)。错误码与触发条件的对应关系见上文「校验链」。Bean Validation 失败(deviceId/targetUsername 缺失、deviceManage 超长)走请求校验出口(请求校验族,判定口径见错误响应差异)。
边界:
deviceId 解析不到发起方租户的直接拥有投影,走「设备不存在」出口。无客户端长连接资源需要释放。发起成功后双方都应重新拉取设备列表/分享记录刷新界面;服务端不向受赠方推送实时通知,App 侧的「对方收到分享」体验需要自建轮询或刷新时机。
未执行真实联调:受赠方可见延迟、目标用户多租户场景下 personal-space 租户的选取顺序(遍历成员租户取第一个命中)均无 App 实测佐证。App 侧对上列五个业务错误码之外应保留未知码兜底分支。