feat(weibo): 修正绑定小程序码并增加账号批量操作

This commit is contained in:
yml2213
2026-11-08 13:17:29 +08:00
parent 79cfd4a634
commit ed15701392
11 changed files with 591 additions and 54 deletions
+22 -5
View File
@@ -43,6 +43,7 @@ from ..services.weibo_service import (
disable_weibo_account,
enable_weibo_account,
exchange_weibo_goods,
generate_weibo_bind_qrcode,
generate_weibo_bind_schemes,
import_weibo_cookies,
query_weibo_exchange_records,
@@ -349,12 +350,14 @@ def refresh_account(
@router.post("/accounts/{account_id}/bind-qrcodes", response_model=WeiboBindQrOut)
def create_bind_qrcodes(
account_id: int,
channel: str = Query("", pattern="^(wx|qq)?$"),
db: Session = Depends(get_db),
current: User = Depends(get_current_user),
):
"""生成微信和 QQ 绑定 Scheme,供前端直接渲染二维码。"""
_require_weibo_perm(current, "weibo:bind")
selected_channel = channel.strip() if isinstance(channel, str) else ""
account = _get_account(db, account_id)
_ensure_enabled(account)
snapshot = _refresh_or_http(account, db)
@@ -370,15 +373,29 @@ def create_bind_qrcodes(
if not snapshot.bind_url:
raise HTTPException(status_code=409, detail="微博没有返回当前账号的绑定链接")
schemes = [
WeiboBindSchemeOut(**item)
for item in generate_weibo_bind_schemes(account, snapshot.bind_url)
if selected_channel:
items = [
generate_weibo_bind_qrcode(account, snapshot.bind_url, selected_channel)
]
else:
# 不传 channel 时保留旧接口:一次返回微信、QQ 两个 Scheme。
items = generate_weibo_bind_schemes(account, snapshot.bind_url)
schemes = [WeiboBindSchemeOut(**item) for item in items]
successful = [
item
for item in schemes
if (item.qrcode_image if selected_channel else item.scheme)
]
successful = [item for item in schemes if item.scheme]
if not successful:
prefix = (
f"{schemes[0].label}绑定二维码生成失败"
if selected_channel and schemes
else "微信和 QQ 绑定二维码都生成失败"
)
raise HTTPException(
status_code=502,
detail="微信和 QQ 绑定二维码都生成失败: "
detail=prefix
+ ": "
+ "; ".join(f"{item.label}={item.error}" for item in schemes if item.error),
)
+2
View File
@@ -522,6 +522,8 @@ class WeiboBindSchemeOut(BaseModel):
channel: str
label: str
scheme: str = ""
qrcode_image: str = ""
qrcode_token: str = ""
error: str = ""
+38
View File
@@ -222,6 +222,44 @@ def generate_weibo_bind_schemes(
return result
def generate_weibo_bind_qrcode(
account: WeiboAccount,
bind_url: str,
channel: str,
) -> dict[str, str]:
"""生成指定渠道的小程序码,并尽力附带可复制的 Scheme。"""
_ = account
label = {"wx": "微信", "qq": "QQ"}[channel]
client = WeiboClient()
try:
qrcode = client.generate_bind_qrcode(bind_url, channel)
except (WeiboError, ValueError) as exc:
return {
"channel": channel,
"label": label,
"scheme": "",
"qrcode_image": "",
"qrcode_token": "",
"error": str(exc),
}
scheme = ""
try:
scheme = client.generate_bind_scheme(bind_url, channel)
except (WeiboError, ValueError):
# 二维码图片是主结果,Scheme 仅用于复制,不影响扫码绑定。
pass
return {
"channel": channel,
"label": label,
"scheme": scheme,
"qrcode_image": qrcode.image_src,
"qrcode_token": qrcode.token,
"error": "",
}
def _effective_activity(account: WeiboAccount, fallback: str) -> str:
return account.activity or fallback