feat(api): allow withdraw of in-approval vehicle recharge applies

Applicants can return an in-approval apply to draft while keeping prior approval rows.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
zlwuandCursor committed 2026-09-29 12:08:48 +08:00
1 parent 388eb8cc7e
commit d8df5c47e2
2 files changed
+55 -4

No files matched your search

+13
View File
@@ -336,6 +336,19 @@ def cancel_apply(
return svc.cancel_apply(db, tenant_no, user, id, mine_vehicles=mine_vehicles)
@apply_router.post("/{id}/withdraw", response_model=VehicleRechargeApplyRead)
def withdraw_apply(
id: str,
mine_vehicles: bool = Query(default=False, alias="mineVehicles"),
db: Session = Depends(get_db),
user: DbUserContext = Depends(get_db_current_user),
) -> VehicleRechargeApplyRead:
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
return svc.withdraw_apply(
db, tenant_no, user, id, mine_vehicles=mine_vehicles
)
@apply_router.delete("/{ids}", status_code=status.HTTP_204_NO_CONTENT)
def delete_applies(
ids: str,
@@ -30,7 +30,10 @@ from app.schemas.pl.vehicle_recharge import (
VehicleRechargeRecordUpdate,
)
from app.services.pl_data_scope import apply_pl_scope, assert_pl_row_in_scope
from app.services.pl_vehicle_mine_vehicles import license_plates_for_user_personnel
from app.services.pl_vehicle_mine_vehicles import (
license_plates_for_user_personnel,
should_restrict_mine_vehicles,
)
_EDITABLE_STATUSES = frozenset({"draft", "rejected"})
_BIZ_TYPE_VEHICLE_RECHARGE = "vehicle_recharge"
@@ -135,11 +138,13 @@ def _get_apply_row(
)
if not row:
raise HTTPException(status_code=404, detail="申请单不存在")
if mine_vehicles:
if should_restrict_mine_vehicles(
db, tenant_no, user.id, mine_vehicles=mine_vehicles
):
plates = license_plates_for_user_personnel(db, tenant_no, user.id)
if row.license_plate not in plates:
raise HTTPException(status_code=403, detail="无权查看该申请")
else:
elif not mine_vehicles:
assert_pl_row_in_scope(db, row, PlVehicleRechargeApply, user, tenant_no)
return row
@@ -530,11 +535,16 @@ def list_applies(
if ids:
query = query.filter(PlVehicleRechargeApply.id.in_(ids))
if mine_vehicles:
if should_restrict_mine_vehicles(
db, tenant_no, user.id, mine_vehicles=mine_vehicles
):
plates = license_plates_for_user_personnel(db, tenant_no, user.id)
if not plates:
return [], 0
query = query.filter(PlVehicleRechargeApply.license_plate.in_(plates))
elif mine_vehicles:
# 管理员 + mineVehicles:本租户全量,跳过挂靠与数据范围
pass
else:
query = apply_pl_scope(query, PlVehicleRechargeApply, user, db, tenant_no)
total = query.count()
@@ -567,6 +577,10 @@ def get_apply(
def _assert_mine_vehicle_plate(
db: Session, tenant_no: str, user: DbUserContext, plate: str
) -> None:
if not should_restrict_mine_vehicles(
db, tenant_no, user.id, mine_vehicles=True
):
return
plates = license_plates_for_user_personnel(db, tenant_no, user.id)
if (plate or "").strip() not in plates:
raise HTTPException(status_code=403, detail="只能选择本人车辆")
@@ -684,6 +698,30 @@ def cancel_apply(
return apply_to_read(row, db)
def withdraw_apply(
db: Session,
tenant_no: str,
user: DbUserContext,
apply_id: str,
*,
mine_vehicles: bool = False,
) -> VehicleRechargeApplyRead:
row = _get_apply_row(
db, tenant_no, apply_id, user, mine_vehicles=mine_vehicles
)
if (row.applicant_id or "").strip() != (user.id or "").strip():
raise HTTPException(status_code=403, detail="仅申请人可撤回")
if row.status != "in_approval":
raise HTTPException(status_code=400, detail="仅审批中的申请可撤回")
row.status = "draft"
row.current_node = None
row.update_by = user.id
row.update_time = datetime.now()
db.commit()
db.refresh(row)
return apply_to_read(row, db, include_detail=True)
def submit_apply(
db: Session,
tenant_no: str,