feat: 新增用车需求服务及线索管理全功能

- 新增后台用车服务配置模块,支持维护服务简介、优势与使用流程
- 新增需求线索管理页面,支持筛选、查看与更新用车线索状态
- 新增小程序用车需求页面,优化登录路径与回跳逻辑
- 优化车型卡片跳转与用车需求提交功能
- 新增服务端API与数据处理逻辑,完善权限校验
- 更新全站配置与API文档,新增相关测试用例
This commit is contained in:
duanshuwen committed 2026-08-22 21:48:08 +08:00
1 parent b7a81964c9
commit d42f69bd47
36 files changed
+1290 -33

No files matched your search

+29 -1
View File
@@ -32,6 +32,7 @@ from ..models import (
MediaAsset,
SiteVersion,
VehicleOption,
VehicleServiceConfig,
WanfaCategory,
WanfaRoute,
utc_now,
@@ -153,6 +154,17 @@ SITE_CONFIG_MODULES = {
"empty_to_none": {"description", "image"},
"create_defaults": {"description": None, "image": None},
},
"vehicleService": {
"model": VehicleServiceConfig,
"entity": "vehicle_service_config",
"primary": "introTitle",
"fields": {"introTitle", "intro", "serviceSections", "advantages", "processSteps", "isActive"},
"none_to_empty": set(),
"empty_to_none": set(),
"create_defaults": {"intro": "", "serviceSections": [], "advantages": [], "processSteps": []},
"ordered": False,
"singleton": True,
},
}
def media_error(status_code: int, message: str, code: str, details: dict | None = None) -> None:
@@ -318,8 +330,16 @@ def normalize_string_list(value) -> list[str]:
def site_field_value(config: dict, field: str, value):
if field in {"steps", "chips"}:
if field in {"steps", "chips", "advantages"}:
return normalize_string_list(value)
if field in {"serviceSections", "processSteps"}:
return [
{key: item_value.strip() for key, item_value in item.model_dump().items() if isinstance(item_value, str)}
if hasattr(item, "model_dump")
else {key: item_value.strip() for key, item_value in item.items() if isinstance(item_value, str)}
for item in (value or [])
if isinstance(item, dict) or hasattr(item, "model_dump")
]
value = clean_site_value(value)
if value == "" and field in config.get("empty_to_none", set()):
return None
@@ -1254,6 +1274,10 @@ def admin_site_config(_user: AdminUser = Depends(require_admin), db: Session = D
model_dict(item)
for item in db.scalars(select(VehicleOption).order_by(VehicleOption.sortOrder.asc())).all()
],
"vehicleService": [
model_dict(item)
for item in db.scalars(select(VehicleServiceConfig).order_by(VehicleServiceConfig.createdAt.asc())).all()
],
"demandHero": [
model_dict(item)
for item in db.scalars(select(DemandHero).order_by(DemandHero.sortOrder.asc())).all()
@@ -1372,6 +1396,7 @@ def delete_site_config(
@router.get("/leads")
def list_leads(
leadType: str | None = None,
status_value: LeadStatus | None = Query(default=None, alias="status"),
sourcePage: str | None = None,
keyword: str | None = None,
@@ -1382,6 +1407,7 @@ def list_leads(
db: Session = Depends(get_db),
):
query = LeadQuery(
leadType=leadType,
status=status_value,
sourcePage=sourcePage,
keyword=keyword,
@@ -1397,6 +1423,8 @@ def list_leads(
)
if query.status:
stmt = stmt.where(Lead.status == query.status)
if query.leadType:
stmt = stmt.where(Lead.leadType == query.leadType)
if query.sourcePage:
stmt = stmt.where(Lead.sourcePage == query.sourcePage.strip())
if query.createdFrom: