WechatOnCloud/bridge/woc_bridge/models/moment.py
Kris 2348a04163 feat: 完成微信4.0模板UI重构与批量群发、导出功能落地
本次提交包含多项核心更新:
1. 新增微信4.0浅色主题UI模板资源与说明文档,补充了联系人图标、新的朋友入口等四个UI元素的图像匹配模板
2. 重构UI驱动层,将原2375行的单文件拆分为5个职责清晰的子驱动类,提升代码可维护性
3. 新增批量群发消息与聊天记录导出的完整数据模型、路由与后台协程,支持幂等校验与风控配置
4. 为所有业务接口新增post_verify校验逻辑,补充了verified字段返回操作结果
5. 优化媒体文件解密逻辑,修复了导出功能中的数据库错误处理与分辨率硬编码问题
6. 更新版本配置,将媒体发送功能标记为已落地,调整了能力列表与配置项
2026-07-16 16:53:42 +08:00

174 lines
6.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""朋友圈域模型:发表朋友圈 / 分享公众号文章到朋友圈。"""
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_idbridge 本地生成的朋友圈发表 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_idbridge 本地生成的分享 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_foundDB 存在但无朋友圈表
- db_encryptedDB 加密且无法解密
- 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="失败时的错误描述")
verified: Optional[bool] = Field(
default=None,
description="post_verify 校验结果True=截图 absdiff 检测到点赞位置像素变化,"
"False=未检测到变化None=未执行校验",
)
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="失败时的错误描述")
verified: Optional[bool] = Field(
default=None,
description="post_verify 校验结果True=MomentsComment 表出现新评论或截图检测到变化,"
"False=未检测到None=未执行校验",
)
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="失败时的错误描述")
verified: Optional[bool] = Field(
default=None,
description="post_verify 校验结果True=MomentsPost 表对应记录已删除,"
"False=记录仍存在None=未执行校验",
)
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="失败时的错误描述")