feat(huya): 客服开放精英宝典工作台与外部 CK 导入
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
- **斗鱼**:极验滑块自动过验、邮箱验证码、批量登录与 CK 检测/重登;精英宝典 / 电竞手册 / 和平小店三套工作台(绑定、开通、充值、兑换);鱼翅可由微信二维码或供应商直充。
|
||||
- **虎牙**:Cookie / 密码 / App / 短信登录、自动注册、设备绑定、精英宝典、浏览器人工兑换;网页运行 Cookie 与 App 原始凭据(`raw_cookie`)分离,可从原始凭据重建网页 Cookie。
|
||||
- **应用宝**:和平精英点券扫码登录、选区服角色、支付二维码。Worker 合在 Web 容器内,只监听 `127.0.0.1:8810`。
|
||||
- **权限**:超级管理员 / 运营 / 客服;可按权限点覆盖。客服只看分配给自己的账号,虎牙侧默认只开放浏览器兑换。
|
||||
- **权限**:超级管理员 / 运营 / 客服;可按权限点覆盖。客服只看分配给自己的账号,虎牙侧默认开放精英宝典(含外部 CK 导入)与浏览器兑换。
|
||||
- **安全**:密码、邮箱、Cookie、代理密钥等敏感字段落盘加密;操作写审计日志。
|
||||
|
||||
## 项目结构
|
||||
@@ -120,7 +120,7 @@ python3 -c 'import secrets; print(secrets.token_urlsafe(32))'
|
||||
|---|---|
|
||||
| 超级管理员 | 全部功能 + 用户管理 + 权限分配 + 审计日志 |
|
||||
| 运营 | 账号管理、批量登录、代理、Cookie、双平台任务、应用宝 |
|
||||
| 客服 | 仅查看分配给自己的账号;虎牙只保留浏览器兑换 |
|
||||
| 客服 | 仅查看分配给自己的账号;虎牙保留精英宝典(含外部 CK 导入)与浏览器兑换 |
|
||||
|
||||
## 登录与任务流
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## 入口与账号范围
|
||||
|
||||
独立页面:虎牙 → 浏览器兑换。导航按角色区分:客服只看到浏览器兑换一个入口;管理员/运营仍显示完整的虎牙菜单(账号管理、精英宝典等)。
|
||||
独立页面:虎牙 → 浏览器兑换。导航按角色区分:客服默认看到精英宝典与浏览器兑换;管理员/运营仍显示完整的虎牙菜单(账号管理、精英宝典等)。
|
||||
|
||||
- 页面维护一份「兑换账号列表」,通过「导入账号」从自己可见的账号池勾选加入;客服只能看到分配给自己的账号。
|
||||
- 列表按用户隔离保存(工作台 scope `browser_exchange`),与精英宝典的账号集合互不影响。
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
"""工作台「导入外部 CK」:入库 + 自动加入工作台 + 归属导入者。"""
|
||||
|
||||
import pytest
|
||||
from fastapi import HTTPException
|
||||
|
||||
from tests.support.db import get_test_engine, make_test_session
|
||||
from web.backend.models import HuyaAccount, HuyaWorkbench, HuyaWorkbenchAccount, User
|
||||
from web.backend.permissions import ROLE_PERMISSIONS
|
||||
from web.backend.routers.huya import import_workbench_cookies
|
||||
from web.backend.routers.huya._common import _require_huya_workbench_import_ck
|
||||
from web.backend.schemas import HuyaWorkbenchCookieImport
|
||||
|
||||
COOKIE_1 = (
|
||||
@@ -79,3 +84,18 @@ class TestImportExternalCkToWorkbench:
|
||||
assert result["account_ids"] == []
|
||||
assert self.session.query(HuyaAccount).count() == 0
|
||||
assert self.session.query(HuyaWorkbench).count() == 0
|
||||
|
||||
def test_support_can_import_workbench_ck_by_default(self):
|
||||
"""客服默认允许工作台导入外部 CK,但旧 huya:import 仍只属于运营。"""
|
||||
assert "huya:elite:import_ck" in ROLE_PERMISSIONS["support"]
|
||||
assert "huya:elite:import_ck" not in ROLE_PERMISSIONS["operation"]
|
||||
|
||||
support = User(username="cs", password_hash="hash", role="support")
|
||||
operation = User(username="op", password_hash="hash", role="operation")
|
||||
guest = User(username="guest", password_hash="hash", role="guest")
|
||||
assert _require_huya_workbench_import_ck(support) is None
|
||||
assert _require_huya_workbench_import_ck(operation) is None
|
||||
|
||||
with pytest.raises(HTTPException) as excinfo:
|
||||
_require_huya_workbench_import_ck(guest)
|
||||
assert excinfo.value.status_code == 403
|
||||
|
||||
@@ -66,6 +66,7 @@ PERMISSIONS = {
|
||||
"huya:cookie:view": "查看虎牙 Cookie",
|
||||
"huya:cookie:export": "导出/清除虎牙 Cookie",
|
||||
"huya:task": "虎牙任务管理",
|
||||
"huya:elite:import_ck": "精英宝典工作台导入外部 CK",
|
||||
"huya:bind": "虎牙绑定操作",
|
||||
"huya:recharge": "虎牙充值操作",
|
||||
"huya:config": "虎牙配置管理",
|
||||
@@ -176,6 +177,7 @@ ROLE_PERMISSIONS = {
|
||||
"huya:view_assigned",
|
||||
"huya:tag",
|
||||
"huya:task",
|
||||
"huya:elite:import_ck",
|
||||
# 客服能看能改(共享表,靠审计留痕),但删除只给运营。
|
||||
"huya:collab:view",
|
||||
"huya:collab:edit",
|
||||
|
||||
@@ -132,6 +132,15 @@ def _require_huya_perm(user: User, permission: str) -> None:
|
||||
raise HTTPException(status_code=403, detail="权限不足")
|
||||
|
||||
|
||||
def _require_huya_workbench_import_ck(user: User) -> None:
|
||||
"""工作台导入外部 CK 的专用权限;运营仍走历史 huya:import。"""
|
||||
if not (
|
||||
_has_huya_perm(user, "huya:import")
|
||||
or _has_huya_perm(user, "huya:elite:import_ck")
|
||||
):
|
||||
raise HTTPException(status_code=403, detail="权限不足")
|
||||
|
||||
|
||||
def _require_huya_tag_permission(user: User) -> None:
|
||||
"""标签权限兼容历史上使用导入权限的运营人员。"""
|
||||
if not (_has_huya_perm(user, "huya:tag") or _has_huya_perm(user, "huya:import")):
|
||||
|
||||
@@ -414,7 +414,7 @@ def import_workbench_cookies(
|
||||
导入后的账号会出现在工作台账号列表里,可照常执行「生成开通支付码 / 绑定二维码 /
|
||||
查询角色 / 刷新积分」等操作。没有归属的新账号自动归属到导入者,否则客服看不到。
|
||||
"""
|
||||
_require_huya_perm(current, "huya:import")
|
||||
_require_huya_workbench_import_ck(current)
|
||||
accounts, skipped = import_huya_cookies_detailed(
|
||||
db, req.text, req.tag, assign_to=current.id
|
||||
)
|
||||
|
||||
@@ -91,9 +91,10 @@ export default function MainLayout({ onLogout }: { onLogout?: () => void }) {
|
||||
douyuItems.push({ key: '/douyu/collab', label: '外部单协作', icon: <FileExcelOutlined /> });
|
||||
}
|
||||
|
||||
// 虎牙:客服只保留浏览器兑换;管理员/运营显示完整入口
|
||||
// 虎牙:客服用浏览器兑换和精英宝典;管理员/运营显示完整入口
|
||||
if (can('huya:task')) {
|
||||
if (user?.role === 'support') {
|
||||
huyaItems.push({ key: '/huya/elite', label: '精英宝典', icon: <BookOutlined /> });
|
||||
huyaItems.push({ key: '/huya/browser-exchange', label: '浏览器兑换', icon: <GlobalOutlined /> });
|
||||
} else {
|
||||
if (canAny(['huya:account', 'huya:view_all', 'huya:view_assigned'])) {
|
||||
|
||||
@@ -164,7 +164,7 @@ function taskQrUrl(task: HuyaTaskItem | undefined): string {
|
||||
export default function HuyaElitePage() {
|
||||
const { can } = usePermissions();
|
||||
const canConfig = can('huya:config');
|
||||
const canImport = can('huya:import');
|
||||
const canImport = can('huya:import') || can('huya:elite:import_ck');
|
||||
const [pool, setPool] = useState<HuyaAccountItem[]>([]);
|
||||
const [accounts, setAccounts] = useState<HuyaAccountItem[]>([]);
|
||||
const [selectedIds, setSelectedIds] = useState<number[]>([]);
|
||||
|
||||
Reference in New Issue
Block a user