feat: 账号管理支持按账号名批量选号打标签,并支持复制账号名

This commit is contained in:
yml2213
2026-10-20 17:31:39 +08:00
parent c299f63537
commit c778ae9a09
8 changed files with 465 additions and 10 deletions
+96
View File
@@ -98,6 +98,20 @@ def _query_bool(value) -> bool:
return value is True
def _parse_account_names(raw_names: str) -> list[str]:
"""解析粘贴的账号名:每行一个,去空白并按输入顺序去重。"""
names: list[str] = []
seen: set[str] = set()
for value in (
(raw_names or "").replace("\r\n", "\n").replace("\r", "\n").split("\n")
):
name = value.strip()
if name and name not in seen:
names.append(name)
seen.add(name)
return names
def _filter_accounts_query(
db: Session,
query,
@@ -109,6 +123,7 @@ def _filter_accounts_query(
tag: str | None = None,
has_cookie: bool = False,
search: str = "",
account_names: str = "",
status: str = "",
ck_status: str = "",
failure_kind: str = "",
@@ -140,6 +155,9 @@ def _filter_accounts_query(
tag_value = _query_str(tag)
if tag_value:
query = query.filter(Account.tag == tag_value)
selected_names = _parse_account_names(_query_str(account_names))
if selected_names:
query = query.filter(Account.username.in_(selected_names))
status_value = _query_str(status)
if status_value:
query = query.filter(Account.status == status_value)
@@ -248,6 +266,7 @@ def _selected_account_ids(
tag=req.tag,
has_cookie=req.has_cookie,
search=req.search,
account_names=req.account_names,
status=req.status,
ck_status=req.ck_status,
failure_kind=req.failure_kind,
@@ -398,6 +417,9 @@ def list_accounts(
),
assigned_user_id: int | None = Query(None, description="只看某个客服名下的账号"),
tag: str = Query(None),
account_names: str = Query(
"", description="多行斗鱼账号名(每行一个),精确匹配并自动去重"
),
has_cookie: bool = Query(False),
search: str = Query(""),
status: str = Query("", description="按生命周期状态筛选;空=全部(不含归档)"),
@@ -446,6 +468,7 @@ def list_accounts(
tag=tag,
has_cookie=has_cookie,
search=search,
account_names=account_names,
status=status,
ck_status=ck_status,
failure_kind=failure_kind,
@@ -623,6 +646,79 @@ def list_accounts(
return result
@router.get("/ids")
def list_account_ids(
assigned_only: bool = Query(False),
assign_status: str = Query(""),
assigned_user_id: int | None = Query(None),
tag: str = Query(None),
has_cookie: bool = Query(False),
search: str = Query(""),
account_names: str = Query(
"", description="多行斗鱼账号名(每行一个),精确匹配并自动去重"
),
status: str = Query(""),
ck_status: str = Query(""),
failure_kind: str = Query(""),
bind_status: str = Query(""),
high_value_filter: str = Query(""),
min_points: int | None = Query(None),
max_points: int | None = Query(None),
min_gold: float | None = Query(None),
max_gold: float | None = Query(None),
elite_opened: bool | None = Query(None),
esports_opened: bool | None = Query(None),
role_bind_status: str = Query(""),
db: Session = Depends(get_db),
current: User = Depends(get_current_user),
):
"""返回当前筛选条件下的全部账号 ID,并按粘贴的账号名顺序排序。
前端「按账号名批量选号」用它一次性拿到所有匹配 ID,再写入表格的选择集,
这样跨分页勾选和后续批量标签都不受当前页限制。
"""
query = _filter_accounts_query(
db,
_visible_accounts_query(db, current),
current,
assigned_only=assigned_only,
assign_status=assign_status,
assigned_user_id=assigned_user_id,
tag=tag,
has_cookie=has_cookie,
search=search,
account_names=account_names,
status=status,
ck_status=ck_status,
failure_kind=failure_kind,
bind_status=bind_status,
high_value_filter=high_value_filter,
min_points=min_points,
max_points=max_points,
min_gold=min_gold,
max_gold=max_gold,
elite_opened=elite_opened,
esports_opened=esports_opened,
role_bind_status=role_bind_status,
)
selected_names = _parse_account_names(_query_str(account_names))
if selected_names:
input_order = case(
{name: index for index, name in enumerate(selected_names)},
value=Account.username,
else_=len(selected_names),
)
query = query.order_by(input_order, Account.id.desc())
else:
query = query.order_by(Account.id.desc())
rows = query.with_entities(Account.id, Account.username).all()
return {
"account_ids": [account_id for account_id, _ in rows],
"usernames": [username for _, username in rows],
"total": len(rows),
}
@router.get("/summary")
def accounts_summary(
db: Session = Depends(get_db),
+2
View File
@@ -130,6 +130,8 @@ class AccountBulkSelection(BaseModel):
all_matching: bool = False
search: str = ""
tag: str = ""
#: 多行斗鱼账号名(每行一个),与其它筛选条件叠加
account_names: str = ""
assigned_only: bool = False
#: 归属筛选:""=全部 / unassigned=未分配 / assigned=已分配
assign_status: str = ""