本次提交将woc-bridge项目重构为模块化包结构,按职责拆分多个子域: 1. 新增models层定义所有Pydantic数据模型与统一错误体系 2. 拆分db/ui/messaging/routes等业务域模块 3. 实现基础API路由:状态查询、截图、登录、媒体获取等 4. 重构tools脚本的模块导入路径 5. 补充版本号与能力清单定义 6. 完善全局配置与依赖管理 整体完成项目从单文件脚本到可维护的包结构迁移,为后续功能开发打下基础。
159 lines
5.9 KiB
Python
159 lines
5.9 KiB
Python
"""朋友圈域模型:发表朋友圈 / 分享公众号文章到朋友圈。"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from typing import Optional
|
||
|
||
from pydantic import BaseModel, Field
|
||
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# 朋友圈接口(POST /api/moments/publish)
|
||
# ---------------------------------------------------------------------------
|
||
class MomentPublishRequest(BaseModel):
|
||
"""发表朋友圈请求(纯文字)。
|
||
|
||
MVP 仅支持纯文字朋友圈。图片朋友圈涉及文件选择器交互,留给后续。
|
||
"""
|
||
|
||
content: str = Field(description="朋友圈文字内容")
|
||
|
||
|
||
class MomentPublishResponse(BaseModel):
|
||
"""发表朋友圈响应。
|
||
|
||
字段说明:
|
||
- local_moment_id:bridge 本地生成的朋友圈发表 ID,格式
|
||
moment_<unix秒>_<随机>。仅用于客户端幂等去重,不对应微信原生
|
||
朋友圈 ID。
|
||
- placeholder:恒为 false(真实执行 UI 发表操作,非占位)。
|
||
"""
|
||
|
||
success: bool = Field(default=False)
|
||
local_moment_id: str = Field(default="", description="本地生成的朋友圈发表 ID")
|
||
placeholder: bool = Field(default=False, description="是否为占位实现(恒为 false)")
|
||
error: Optional[str] = Field(default=None, description="失败时的错误描述")
|
||
|
||
|
||
class MomentShareArticleRequest(BaseModel):
|
||
"""分享公众号文章到朋友圈请求。
|
||
|
||
通过搜索公众号名称进入会话,点击第 N 篇推送文章卡片打开文章页,
|
||
再经「分享到朋友圈」UI 路径生成带卡片预览的朋友圈。
|
||
"""
|
||
|
||
public_account: str = Field(
|
||
description="公众号名称或 wxid,用于搜索定位公众号会话"
|
||
)
|
||
article_index: int = Field(
|
||
default=1,
|
||
description="从会话顶部往下的第几篇推送文章卡片,默认 1(最新一篇)",
|
||
)
|
||
comment: Optional[str] = Field(
|
||
default=None,
|
||
description="可选:分享时附带的「说点什么」评论文字,不传则跳过",
|
||
)
|
||
|
||
|
||
class MomentShareArticleResponse(BaseModel):
|
||
"""分享公众号文章到朋友圈响应。
|
||
|
||
字段说明:
|
||
- local_moment_id:bridge 本地生成的分享 ID,格式
|
||
share_<unix秒>_<随机>。仅用于客户端幂等去重。
|
||
- placeholder:恒为 false(真实执行 UI 分享操作,非占位)。
|
||
"""
|
||
|
||
success: bool = Field(default=False)
|
||
local_moment_id: str = Field(default="", description="本地生成的分享 ID")
|
||
placeholder: bool = Field(default=False, description="是否为占位实现(恒为 false)")
|
||
error: Optional[str] = Field(default=None, description="失败时的错误描述")
|
||
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# 朋友圈时间线(GET /api/moments/timeline)
|
||
# ---------------------------------------------------------------------------
|
||
class MomentItem(BaseModel):
|
||
"""单条朋友圈。"""
|
||
|
||
moment_id: str = Field(description="朋友圈 ID")
|
||
content: str = Field(default="", description="文字内容")
|
||
create_time: int = Field(description="发布时间戳(Unix 秒)")
|
||
author_wxid: str = Field(default="", description="发布者 wxid")
|
||
|
||
|
||
class MomentsTimelineResponse(BaseModel):
|
||
"""朋友圈时间线响应。
|
||
|
||
status 字段说明(因 WeChat 4.x 朋友圈 schema 未公开,需容错探测):
|
||
- ok:正常读取
|
||
- db_not_found:未找到朋友圈 DB 文件
|
||
- table_not_found:DB 存在但无朋友圈表
|
||
- db_encrypted:DB 加密且无法解密
|
||
- no_time_column / no_columns / query_error:探测/查询失败
|
||
"""
|
||
|
||
moments: list[MomentItem] = Field(default_factory=list)
|
||
next_cursor: int = Field(description="下次拉取应使用的 cursor")
|
||
has_more: bool = Field(default=False, description="是否可能还有更多")
|
||
status: str = Field(default="", description="探测/查询状态码")
|
||
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# 朋友圈互动(experimental)
|
||
# ---------------------------------------------------------------------------
|
||
class MomentLikeRequest(BaseModel):
|
||
"""朋友圈点赞请求(experimental)。"""
|
||
|
||
moment_index: int = Field(default=1, description="朋友圈序号,1=最新")
|
||
|
||
|
||
class MomentLikeResponse(BaseModel):
|
||
"""朋友圈点赞响应。"""
|
||
|
||
success: bool = Field(default=False)
|
||
error: Optional[str] = Field(default=None, description="失败时的错误描述")
|
||
|
||
|
||
class MomentCommentRequest(BaseModel):
|
||
"""朋友圈评论请求(experimental)。"""
|
||
|
||
comment: str = Field(description="评论文字内容")
|
||
moment_index: int = Field(default=1, description="朋友圈序号,1=最新")
|
||
|
||
|
||
class MomentCommentResponse(BaseModel):
|
||
"""朋友圈评论响应。"""
|
||
|
||
success: bool = Field(default=False)
|
||
error: Optional[str] = Field(default=None, description="失败时的错误描述")
|
||
|
||
|
||
class MomentDeleteRequest(BaseModel):
|
||
"""删除朋友圈请求(experimental)。"""
|
||
|
||
moment_index: int = Field(default=1, description="朋友圈序号,1=最新")
|
||
|
||
|
||
class MomentDeleteResponse(BaseModel):
|
||
"""删除朋友圈响应。"""
|
||
|
||
success: bool = Field(default=False)
|
||
error: Optional[str] = Field(default=None, description="失败时的错误描述")
|
||
|
||
|
||
class MomentPublishImageRequest(BaseModel):
|
||
"""发表图片朋友圈请求(experimental)。"""
|
||
|
||
image_path: str = Field(description="图片文件容器内绝对路径")
|
||
content: str = Field(default="", description="可选文字内容")
|
||
|
||
|
||
class MomentPublishImageResponse(BaseModel):
|
||
"""发表图片朋友圈响应。"""
|
||
|
||
success: bool = Field(default=False)
|
||
local_moment_id: str = Field(default="", description="本地生成的朋友圈 ID")
|
||
placeholder: bool = Field(default=False, description="是否为占位实现(恒为 false)")
|
||
error: Optional[str] = Field(default=None, description="失败时的错误描述")
|