1. 数据库新增迁移 20261003_0040,在 douyu_tasks 表增加 account_assigned_to 字段,并创建 (account_assigned_to, handbook_scope, id) 与 (account_assigned_to, id) 复合覆盖索引; 2. 迁移脚本自动回填历史 24 万条任务的所属客服 ID; 3. 任务服务与账号路由联动:创建任务时自动继承 account_assigned_to,修改账号分配时同步更新关联任务归属; 4. 斗鱼任务查询路由 _visible_tasks_query 改为通过 account_assigned_to 复合索引过滤,消除与 accounts 表的跨表关联与临时表全量文件排序; 5. 新增 test_douyu_task_assigned_optimization 单元测试并通过整链迁移与回归测试。
118 lines
3.8 KiB
Python
118 lines
3.8 KiB
Python
"""验证 DouyuTask 的 account_assigned_to 字段与任务查询优化。"""
|
|
|
|
from tests.support.db import init_test_schema, make_test_session
|
|
from web.backend.models import Account, DouyuTask, User
|
|
from web.backend.routers.douyu import _visible_tasks_query
|
|
from web.backend.services.douyu_service import create_douyu_planned_tasks
|
|
|
|
|
|
def test_douyu_task_assigned_to_flow():
|
|
from tests.support.db import get_test_engine
|
|
|
|
init_test_schema()
|
|
DouyuTask.__table__.drop(get_test_engine(), checkfirst=True)
|
|
DouyuTask.__table__.create(get_test_engine(), checkfirst=True)
|
|
db: Session = make_test_session()
|
|
try:
|
|
# 创建测试客服用户与账号
|
|
user_a = User(
|
|
username="test_kefu_a",
|
|
password_hash="fake",
|
|
role="support",
|
|
custom_permissions=["douyu:task", "account:view_assigned"],
|
|
is_active=True,
|
|
)
|
|
user_b = User(
|
|
username="test_kefu_b",
|
|
password_hash="fake",
|
|
role="support",
|
|
custom_permissions=["douyu:task", "account:view_assigned"],
|
|
is_active=True,
|
|
)
|
|
db.add_all([user_a, user_b])
|
|
db.flush()
|
|
|
|
acc_1 = Account(
|
|
username="dy_user_1",
|
|
password="pwd",
|
|
email="em1@test.com",
|
|
email_password="pwd",
|
|
assigned_to=user_a.id,
|
|
)
|
|
acc_2 = Account(
|
|
username="dy_user_2",
|
|
password="pwd",
|
|
email="em2@test.com",
|
|
email_password="pwd",
|
|
assigned_to=user_b.id,
|
|
)
|
|
db.add_all([acc_1, acc_2])
|
|
db.flush()
|
|
|
|
from web.backend.models import LoginTask
|
|
|
|
lt_1 = LoginTask(
|
|
account_id=acc_1.id,
|
|
batch_id="b1",
|
|
status="success",
|
|
cookie="acf_uid=101; acf_auth=fake",
|
|
created_by=user_a.id,
|
|
)
|
|
lt_2 = LoginTask(
|
|
account_id=acc_2.id,
|
|
batch_id="b2",
|
|
status="success",
|
|
cookie="acf_uid=102; acf_auth=fake",
|
|
created_by=user_b.id,
|
|
)
|
|
db.add_all([lt_1, lt_2])
|
|
db.flush()
|
|
|
|
# 1. 验证创建任务时,自动继承 account.assigned_to
|
|
batch_id, count = create_douyu_planned_tasks(
|
|
db=db,
|
|
account_ids=[acc_1.id, acc_2.id],
|
|
task_type="query_points",
|
|
handbook_scope="elite",
|
|
created_by=user_a.id,
|
|
)
|
|
assert count == 2
|
|
|
|
tasks = db.query(DouyuTask).filter(DouyuTask.batch_id == batch_id).all()
|
|
task_map = {t.account_id: t for t in tasks}
|
|
assert task_map[acc_1.id].account_assigned_to == user_a.id
|
|
assert task_map[acc_2.id].account_assigned_to == user_b.id
|
|
|
|
# 2. 验证 _visible_tasks_query 能够精准过滤所属客服
|
|
query_a = _visible_tasks_query(db, user_a).filter(
|
|
DouyuTask.batch_id == batch_id
|
|
)
|
|
visible_a = query_a.all()
|
|
assert len(visible_a) == 1
|
|
assert visible_a[0].account_id == acc_1.id
|
|
|
|
query_b = _visible_tasks_query(db, user_b).filter(
|
|
DouyuTask.batch_id == batch_id
|
|
)
|
|
visible_b = query_b.all()
|
|
assert len(visible_b) == 1
|
|
assert visible_b[0].account_id == acc_2.id
|
|
|
|
# 3. 验证账号重新分配后,关联任务同步变更
|
|
db.query(DouyuTask).filter(DouyuTask.account_id == acc_1.id).update(
|
|
{DouyuTask.account_assigned_to: user_b.id}, synchronize_session=False
|
|
)
|
|
acc_1.assigned_to = user_b.id
|
|
db.commit()
|
|
|
|
# 此时 user_b 可以看到 acc_1 的任务
|
|
visible_b_after = (
|
|
_visible_tasks_query(db, user_b)
|
|
.filter(DouyuTask.batch_id == batch_id)
|
|
.all()
|
|
)
|
|
assert len(visible_b_after) == 2
|
|
finally:
|
|
db.rollback()
|
|
db.close()
|