feat: 新增用车需求服务及线索管理全功能
- 新增后台用车服务配置模块,支持维护服务简介、优势与使用流程 - 新增需求线索管理页面,支持筛选、查看与更新用车线索状态 - 新增小程序用车需求页面,优化登录路径与回跳逻辑 - 优化车型卡片跳转与用车需求提交功能 - 新增服务端API与数据处理逻辑,完善权限校验 - 更新全站配置与API文档,新增相关测试用例
This commit is contained in:
1 parent
b7a81964c9
commit
d42f69bd47
36 files changed
+1290
-33
No files matched your search
@@ -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:
|
||||
|
||||
Reference in new issue
Block a user