feat: 支持按权益名称导入用户

This commit is contained in:
2026-08-19 15:11:49 +08:00
parent efe835be81
commit 6ffdd2c259
5 changed files with 213 additions and 13 deletions

View File

@@ -0,0 +1,120 @@
from __future__ import annotations
from types import SimpleNamespace
from sqlalchemy import create_engine, select
from sqlalchemy.orm import Session
from sqlalchemy.pool import StaticPool
from app.api.admin_users import (
STUDENT_TEMPLATE_HEADERS,
_import_user_items,
_user_import_template_workbook,
)
from app.models import Base
from app.models.entitlement import EntitlementPlan, UserEntitlement
from app.models.user import User
from app.schemas.admin import AdminUserImportItem
def _database() -> Session:
engine = create_engine(
"sqlite:///:memory:",
connect_args={"check_same_thread": False},
poolclass=StaticPool,
)
Base.metadata.create_all(engine)
return Session(engine)
def test_user_import_template_contains_entitlement_name_and_uses_available_plan_example():
with _database() as db:
db.add_all(
[
EntitlementPlan(id=1, name="深度陪伴版", plan_type="deep", status=1, sort_order=1),
EntitlementPlan(id=2, name="已停用版", plan_type="basic", status=0, sort_order=0),
]
)
db.commit()
sheet = _user_import_template_workbook(db).active
assert [cell.value for cell in sheet[1]] == STUDENT_TEMPLATE_HEADERS
assert sheet.cell(row=2, column=7).value == "深度陪伴版"
assert sheet.cell(row=3, column=7).value == ""
def test_user_import_matches_entitlement_by_name_and_clears_missing_or_unknown_names():
with _database() as db:
available = EntitlementPlan(id=1, name="深度陪伴版", plan_type="deep", status=1)
old_plan = EntitlementPlan(id=2, name="旧权益", plan_type="basic", status=1)
disabled = EntitlementPlan(id=3, name="停用权益", plan_type="basic", status=0)
existing_user = User(id=10, phone="13800000010", name="旧姓名", daily_chat_limit=10)
db.add_all([available, old_plan, disabled, existing_user])
db.flush()
db.add(UserEntitlement(user_id=existing_user.id, plan_id=old_plan.id, status="active"))
db.commit()
result = _import_user_items(
[
(
2,
AdminUserImportItem(
phone="13800000011",
name="匹配用户",
entitlementName="深度陪伴版",
),
),
(
3,
AdminUserImportItem(
phone="13800000010",
name="更新用户",
entitlementName="系统不存在的权益",
),
),
(
4,
AdminUserImportItem(
phone="13800000012",
name="留空用户",
entitlementName=None,
),
),
(
5,
AdminUserImportItem(
phone="13800000013",
name="停用权益用户",
entitlementName="停用权益",
),
),
],
db,
SimpleNamespace(id=99),
)
assert result == {"created": 3, "updated": 1, "failed": 0, "failures": []}
matched_user = db.scalar(select(User).where(User.phone == "13800000011"))
matched_entitlement = db.scalar(
select(UserEntitlement).where(
UserEntitlement.user_id == matched_user.id,
UserEntitlement.status == "active",
)
)
assert matched_entitlement is not None
assert matched_entitlement.plan_id == available.id
for phone in ("13800000010", "13800000012", "13800000013"):
user = db.scalar(select(User).where(User.phone == phone))
assert db.scalar(
select(UserEntitlement).where(
UserEntitlement.user_id == user.id,
UserEntitlement.status == "active",
)
) is None
old_entitlement = db.scalar(
select(UserEntitlement).where(UserEntitlement.user_id == existing_user.id)
)
assert old_entitlement.status == "replaced"