新增素材更新功能
This commit is contained in:
@@ -22,6 +22,8 @@ from app.api.v1.user_oauth import router as user_oauth_router
|
||||
from app.api.v1.user_oauth_app import router as user_oauth_app_router
|
||||
from app.api.v1.upload_material import router as upload_material_router
|
||||
from app.api.v1.pre_test_template import router as pre_test_template_router
|
||||
from app.api.v1.material_consumption import router as material_consumption_router
|
||||
from app.api.v1.open_type import router as open_type_router
|
||||
from app.api.admin import router as admin_module_router
|
||||
|
||||
api_router = APIRouter()
|
||||
@@ -47,4 +49,6 @@ api_router.include_router(user_oauth_router)
|
||||
api_router.include_router(user_oauth_app_router)
|
||||
api_router.include_router(upload_material_router)
|
||||
api_router.include_router(pre_test_template_router)
|
||||
api_router.include_router(material_consumption_router)
|
||||
api_router.include_router(open_type_router)
|
||||
api_router.include_router(admin_module_router)
|
||||
|
||||
@@ -0,0 +1,301 @@
|
||||
from typing import Any, Optional
|
||||
from datetime import datetime, timedelta, timezone
|
||||
|
||||
from fastapi import APIRouter, Query, Depends, Body
|
||||
from sqlalchemy import select, func
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.models.user import User
|
||||
from app.models.material_cost import MaterialCost
|
||||
from app.models.user_oauth import UserOAuth
|
||||
from app.models.user_oauth_account import UserOAuthAccount
|
||||
from app.dependencies import get_current_user, get_db
|
||||
from app.services.material_consumption_queue import sync_all_advertisers_consumption, _fetch_and_save_consumption
|
||||
|
||||
router = APIRouter(prefix="/material-consumption", tags=["material-consumption"])
|
||||
|
||||
|
||||
@router.get(
|
||||
"/list",
|
||||
summary="查询素材消耗列表",
|
||||
description="查询当前用户的素材消耗列表",
|
||||
)
|
||||
async def get_consumption_list(
|
||||
page: int = Query(1, ge=1, description="页码"),
|
||||
page_size: int = Query(20, ge=1, le=100, description="每页数量"),
|
||||
advertiser_id: Optional[str] = Query(None, description="广告主ID筛选"),
|
||||
start_date: Optional[str] = Query(None, description="开始日期"),
|
||||
end_date: Optional[str] = Query(None, description="结束日期"),
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
) -> Any | dict:
|
||||
offset = (page - 1) * page_size
|
||||
|
||||
query = (
|
||||
select(MaterialCost)
|
||||
.join(
|
||||
UserOAuth,
|
||||
MaterialCost.oauth_id == UserOAuth.id,
|
||||
)
|
||||
.where(
|
||||
UserOAuth.user_id == current_user.id,
|
||||
MaterialCost.deleted_at.is_(None),
|
||||
UserOAuth.deleted_at.is_(None),
|
||||
)
|
||||
)
|
||||
|
||||
if advertiser_id:
|
||||
query = query.where(MaterialCost.advertiser_id == advertiser_id)
|
||||
|
||||
if start_date:
|
||||
start_date_obj = datetime.strptime(start_date, "%Y-%m-%d").date()
|
||||
query = query.where(MaterialCost.consume_date >= start_date_obj)
|
||||
|
||||
if end_date:
|
||||
end_date_obj = datetime.strptime(end_date, "%Y-%m-%d").date()
|
||||
query = query.where(MaterialCost.consume_date <= end_date_obj)
|
||||
|
||||
result = await db.execute(
|
||||
query.order_by(MaterialCost.consume_date.desc())
|
||||
.offset(offset)
|
||||
.limit(page_size)
|
||||
)
|
||||
consumptions = result.scalars().all()
|
||||
|
||||
count_query = (
|
||||
select(func.count(MaterialCost.id))
|
||||
.join(
|
||||
UserOAuth,
|
||||
MaterialCost.oauth_id == UserOAuth.id,
|
||||
)
|
||||
.where(
|
||||
UserOAuth.user_id == current_user.id,
|
||||
MaterialCost.deleted_at.is_(None),
|
||||
UserOAuth.deleted_at.is_(None),
|
||||
)
|
||||
)
|
||||
|
||||
if advertiser_id:
|
||||
count_query = count_query.where(MaterialCost.advertiser_id == advertiser_id)
|
||||
|
||||
if start_date:
|
||||
start_date_obj = datetime.strptime(start_date, "%Y-%m-%d").date()
|
||||
count_query = count_query.where(MaterialCost.consume_date >= start_date_obj)
|
||||
|
||||
if end_date:
|
||||
end_date_obj = datetime.strptime(end_date, "%Y-%m-%d").date()
|
||||
count_query = count_query.where(MaterialCost.consume_date <= end_date_obj)
|
||||
|
||||
total_result = await db.execute(count_query)
|
||||
total = total_result.scalar_one()
|
||||
|
||||
return {
|
||||
"code": 0,
|
||||
"data": [
|
||||
{
|
||||
"id": consumption.id,
|
||||
"advertiser_id": consumption.advertiser_id,
|
||||
"material_id": consumption.material_id,
|
||||
"consume_date": consumption.consume_date.isoformat() if consumption.consume_date else None,
|
||||
"stat_cost": consumption.stat_cost,
|
||||
"show_cnt": consumption.show_cnt,
|
||||
"cpm_platform": consumption.cpm_platform,
|
||||
"click_cnt": consumption.click_cnt,
|
||||
"ctr": consumption.ctr,
|
||||
"cpc_platform": consumption.cpc_platform,
|
||||
"convert_cnt": consumption.convert_cnt,
|
||||
"conversion_cost": consumption.conversion_cost,
|
||||
"conversion_rate": consumption.conversion_rate,
|
||||
"deep_convert_cnt": consumption.deep_convert_cnt,
|
||||
"deep_convert_cost": consumption.deep_convert_cost,
|
||||
"deep_convert_rate": consumption.deep_convert_rate,
|
||||
"active": consumption.active,
|
||||
"active_cost": consumption.active_cost,
|
||||
"active_rate": consumption.active_rate,
|
||||
"active_register": consumption.active_register,
|
||||
"active_register_cost": consumption.active_register_cost,
|
||||
"active_register_rate": consumption.active_register_rate,
|
||||
"attribution_next_day_open_cnt": consumption.attribution_next_day_open_cnt,
|
||||
"attribution_next_day_open_cost": consumption.attribution_next_day_open_cost,
|
||||
"attribution_next_day_open_rate": consumption.attribution_next_day_open_rate,
|
||||
"active_pay": consumption.active_pay,
|
||||
"active_pay_cost": consumption.active_pay_cost,
|
||||
"active_pay_rate": consumption.active_pay_rate,
|
||||
"phone": consumption.phone,
|
||||
"form": consumption.form,
|
||||
"download_start": consumption.download_start,
|
||||
"form_submit": consumption.form_submit,
|
||||
"button": consumption.button,
|
||||
"view": consumption.view,
|
||||
"message": consumption.message,
|
||||
"consult": consumption.consult,
|
||||
"consult_effective": consumption.consult_effective,
|
||||
"shopping": consumption.shopping,
|
||||
"customer_effective": consumption.customer_effective,
|
||||
"attribution_game_in_app_ltv_1day": consumption.attribution_game_in_app_ltv_1day,
|
||||
"attribution_game_in_app_roi_1day": consumption.attribution_game_in_app_roi_1day,
|
||||
"loan_completion": consumption.loan_completion,
|
||||
"loan_completion_cost": consumption.loan_completion_cost,
|
||||
"loan_completion_rate": consumption.loan_completion_rate,
|
||||
"loan_credit": consumption.loan_credit,
|
||||
"loan_credit_cost": consumption.loan_credit_cost,
|
||||
"loan_credit_rate": consumption.loan_credit_rate,
|
||||
"in_app_order_gmv": consumption.in_app_order_gmv,
|
||||
"in_app_order_roi": consumption.in_app_order_roi,
|
||||
"in_app_pay_gmv": consumption.in_app_pay_gmv,
|
||||
"in_app_pay_roi": consumption.in_app_pay_roi,
|
||||
"total_play": consumption.total_play,
|
||||
"valid_play": consumption.valid_play,
|
||||
"valid_play_cost": consumption.valid_play_cost,
|
||||
"valid_play_rate": consumption.valid_play_rate,
|
||||
"valid_play_of_mille": consumption.valid_play_of_mille,
|
||||
"valid_play_cost_of_mille": consumption.valid_play_cost_of_mille,
|
||||
"average_play_time_per_play": consumption.average_play_time_per_play,
|
||||
"play_over_rate": consumption.play_over_rate,
|
||||
"dy_like": consumption.dy_like,
|
||||
"dy_comment": consumption.dy_comment,
|
||||
"dy_share": consumption.dy_share,
|
||||
"report_cnt": consumption.report_cnt,
|
||||
"created_at": consumption.created_at,
|
||||
}
|
||||
for consumption in consumptions
|
||||
],
|
||||
"pagination": {
|
||||
"page": page,
|
||||
"page_size": page_size,
|
||||
"total": total,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@router.get(
|
||||
"/sync",
|
||||
summary="手动同步素材消耗",
|
||||
description="手动触发素材消耗同步任务,加入队列顺序执行",
|
||||
)
|
||||
async def sync_consumption(
|
||||
date: str = Query(None, description="同步日期,默认为昨天"),
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
) -> Any | dict:
|
||||
if date is None:
|
||||
date = (datetime.now(timezone.utc) - timedelta(days=1)).strftime("%Y-%m-%d")
|
||||
|
||||
# 测试用,手动触发同步素材消耗任务
|
||||
result = await _fetch_and_save_consumption("0019eb9f130027c05b8", "1863675913228435", date)
|
||||
return {
|
||||
"code": 0,
|
||||
"message": result,
|
||||
}
|
||||
result = await sync_all_advertisers_consumption(date)
|
||||
|
||||
return {
|
||||
"code": 0,
|
||||
"message": result["message"],
|
||||
}
|
||||
|
||||
|
||||
@router.get(
|
||||
"/fields",
|
||||
summary="获取素材消耗字段描述",
|
||||
description="返回素材消耗表每个字段对应的中文描述,帮助前端理解字段含义",
|
||||
)
|
||||
async def get_consumption_fields() -> Any | dict:
|
||||
fields = [
|
||||
{"field": "id", "description": "主键"},
|
||||
{"field": "advertiser_id", "description": "广告主id"},
|
||||
{"field": "material_id", "description": "素材id"},
|
||||
{"field": "consume_date", "description": "消耗日期"},
|
||||
{"field": "stat_cost", "description": "消耗金额"},
|
||||
{"field": "show_cnt", "description": "展示数"},
|
||||
{"field": "cpm_platform", "description": "平均千次展现费用(元)"},
|
||||
{"field": "click_cnt", "description": "点击数"},
|
||||
{"field": "ctr", "description": "点击率"},
|
||||
{"field": "cpc_platform", "description": "平均点击单价(元)"},
|
||||
{"field": "convert_cnt", "description": "转化数"},
|
||||
{"field": "conversion_cost", "description": "平均转化成本(元)"},
|
||||
{"field": "conversion_rate", "description": "转化率"},
|
||||
{"field": "deep_convert_cnt", "description": "深度转化数"},
|
||||
{"field": "deep_convert_cost", "description": "深度转化成本(元)"},
|
||||
{"field": "deep_convert_rate", "description": "深度转化率"},
|
||||
{"field": "active", "description": "激活数"},
|
||||
{"field": "active_cost", "description": "激活成本(元)"},
|
||||
{"field": "active_rate", "description": "激活率"},
|
||||
{"field": "active_register", "description": "注册数"},
|
||||
{"field": "active_register_cost", "description": "注册成本(元)"},
|
||||
{"field": "active_register_rate", "description": "注册率"},
|
||||
{"field": "attribution_next_day_open_cnt", "description": "次留数"},
|
||||
{"field": "attribution_next_day_open_cost", "description": "次留成本"},
|
||||
{"field": "attribution_next_day_open_rate", "description": "次留率"},
|
||||
{"field": "active_pay", "description": "首次付费数"},
|
||||
{"field": "active_pay_cost", "description": "首次付费成本(元)"},
|
||||
{"field": "active_pay_rate", "description": "首次付费率"},
|
||||
{"field": "phone", "description": "点击电话按钮"},
|
||||
{"field": "form", "description": "用户在门店落地页多线沟通提交表单的次数"},
|
||||
{"field": "download_start", "description": "用户点击下载开始的次数"},
|
||||
{"field": "form_submit", "description": "用户查看附加创意后,提交表单的次数"},
|
||||
{"field": "button", "description": "用户点击按钮button的次数"},
|
||||
{"field": "view", "description": "用户在关键页面的浏览次数"},
|
||||
{"field": "message", "description": "用户点击短信咨询的次数"},
|
||||
{"field": "consult", "description": "用户点击在线咨询按钮的次数"},
|
||||
{"field": "consult_effective", "description": "用户在门店落地页多线沟通的在线咨询中有效咨询的次数"},
|
||||
{"field": "shopping", "description": "用户购买商品的次数"},
|
||||
{"field": "customer_effective", "description": "有效获客"},
|
||||
{"field": "attribution_game_in_app_ltv_1day", "description": "当日付费金额"},
|
||||
{"field": "attribution_game_in_app_roi_1day", "description": "当日付费ROI"},
|
||||
{"field": "loan_completion", "description": "完件数(互联网金融-贷款行业中,用户成功提交贷款额度申请的行为)"},
|
||||
{"field": "loan_completion_cost", "description": "完件成本(元)"},
|
||||
{"field": "loan_completion_rate", "description": "完件率"},
|
||||
{"field": "loan_credit", "description": "授信数(互联网金融-贷款行业中,用户提交贷款额度申请后,客户审批通过,给予用户可贷款的额度)"},
|
||||
{"field": "loan_credit_cost", "description": "授信成本(元)"},
|
||||
{"field": "loan_credit_rate", "description": "授信率"},
|
||||
{"field": "in_app_order_gmv", "description": "引流电商订单GMV(当您使用\"in_app_order\"事件回传订单金额时,对应的GMV金额)"},
|
||||
{"field": "in_app_order_roi", "description": "引流电商订单ROI"},
|
||||
{"field": "in_app_pay_gmv", "description": "引流电商支付GMV"},
|
||||
{"field": "in_app_pay_roi", "description": "引流电商支付ROI"},
|
||||
{"field": "total_play", "description": "播放量(播放时间大于0S的数量,在某些蜂窝网络环境下,需要您手动点击开始才会开始播放,因此有时播放数小于展示数)"},
|
||||
{"field": "valid_play", "description": "有效播放数"},
|
||||
{"field": "valid_play_cost", "description": "有效播放成本(元)"},
|
||||
{"field": "valid_play_rate", "description": "有效播放率"},
|
||||
{"field": "valid_play_of_mille", "description": "千次有效播放数"},
|
||||
{"field": "valid_play_cost_of_mille", "description": "千次有效播放成本(元)"},
|
||||
{"field": "average_play_time_per_play", "description": "平均单次播放时长"},
|
||||
{"field": "play_over_rate", "description": "完播率"},
|
||||
{"field": "dy_like", "description": "点赞数"},
|
||||
{"field": "dy_comment", "description": "评论量"},
|
||||
{"field": "dy_share", "description": "分享量"},
|
||||
{"field": "report_cnt", "description": "举报数"},
|
||||
{"field": "created_at", "description": "创建时间"},
|
||||
]
|
||||
|
||||
return {
|
||||
"code": 0,
|
||||
"data": fields,
|
||||
}
|
||||
|
||||
|
||||
@router.get(
|
||||
"/advertisers",
|
||||
summary="获取用户的广告主列表",
|
||||
description="获取当前用户有权限的广告主列表,用于筛选",
|
||||
)
|
||||
async def get_advertisers(
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
) -> Any | dict:
|
||||
result = await db.execute(
|
||||
select(UserOAuthAccount.advertiser_id)
|
||||
.join(UserOAuth, UserOAuthAccount.oauth_id == UserOAuth.id)
|
||||
.where(
|
||||
UserOAuth.user_id == current_user.id,
|
||||
UserOAuth.deleted_at.is_(None),
|
||||
UserOAuthAccount.deleted_at.is_(None),
|
||||
)
|
||||
.distinct()
|
||||
)
|
||||
advertisers = result.scalars().all()
|
||||
|
||||
return {
|
||||
"code": 0,
|
||||
"data": [{"advertiser_id": str(aid)} for aid in advertisers],
|
||||
}
|
||||
@@ -0,0 +1,262 @@
|
||||
from typing import Any, Optional
|
||||
|
||||
from fastapi import APIRouter, Body, Depends, HTTPException, Query, status
|
||||
from sqlalchemy import select, func
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.dependencies import get_admin_user, get_db
|
||||
from app.models.user import User
|
||||
from app.models.open_type import OpenType
|
||||
from app.schemas.open_type import (
|
||||
OpenTypeCreate,
|
||||
OpenTypeUpdate,
|
||||
OpenTypeListResponse,
|
||||
OpenTypeResponse,
|
||||
)
|
||||
from app.utils.id_gen import generate_id
|
||||
|
||||
router = APIRouter(prefix="/open-type", tags=["open-type"])
|
||||
|
||||
|
||||
@router.get(
|
||||
"/list",
|
||||
summary="获取开户方式列表",
|
||||
description="获取开户方式列表,支持分页和筛选",
|
||||
response_model=OpenTypeListResponse,
|
||||
)
|
||||
async def get_open_type_list(
|
||||
page: int = Query(1, ge=1, description="页码"),
|
||||
page_size: int = Query(20, ge=1, le=100, description="每页数量"),
|
||||
type_name: Optional[str] = Query(None, description="标题名称筛选"),
|
||||
open_type: Optional[int] = Query(None, description="开户方式id筛选"),
|
||||
admin: User = Depends(get_admin_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
) -> Any | dict:
|
||||
offset = (page - 1) * page_size
|
||||
|
||||
query = select(OpenType).where(OpenType.deleted_at.is_(None))
|
||||
|
||||
if type_name:
|
||||
query = query.where(OpenType.type_name.like(f"%{type_name}%"))
|
||||
|
||||
if open_type:
|
||||
query = query.where(OpenType.open_type == open_type)
|
||||
|
||||
result = await db.execute(
|
||||
query.order_by(OpenType.open_type.asc())
|
||||
.offset(offset)
|
||||
.limit(page_size)
|
||||
)
|
||||
open_types = result.scalars().all()
|
||||
|
||||
count_query = select(func.count(OpenType.id)).where(OpenType.deleted_at.is_(None))
|
||||
if type_name:
|
||||
count_query = count_query.where(OpenType.type_name.like(f"%{type_name}%"))
|
||||
if open_type:
|
||||
count_query = count_query.where(OpenType.open_type == open_type)
|
||||
|
||||
total_result = await db.execute(count_query)
|
||||
total = total_result.scalar_one()
|
||||
|
||||
return {
|
||||
"code": 0,
|
||||
"message": "查询成功",
|
||||
"data": [
|
||||
{
|
||||
"id": item.id,
|
||||
"type_name": item.type_name,
|
||||
"open_type": item.open_type,
|
||||
"description": item.description,
|
||||
"thumb": item.thumb,
|
||||
"created_at": item.created_at,
|
||||
"updated_at": item.updated_at,
|
||||
}
|
||||
for item in open_types
|
||||
],
|
||||
"pagination": {
|
||||
"page": page,
|
||||
"page_size": page_size,
|
||||
"total": total,
|
||||
"total_pages": (total + page_size - 1) // page_size,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@router.get(
|
||||
"/{id}",
|
||||
summary="获取开户方式详情",
|
||||
description="根据ID获取开户方式详情",
|
||||
response_model=OpenTypeResponse,
|
||||
)
|
||||
async def get_open_type_detail(
|
||||
id: str,
|
||||
admin: User = Depends(get_admin_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
) -> Any | dict:
|
||||
result = await db.execute(
|
||||
select(OpenType).where(OpenType.id == id, OpenType.deleted_at.is_(None))
|
||||
)
|
||||
open_type = result.scalar_one_or_none()
|
||||
|
||||
if not open_type:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="开户方式不存在",
|
||||
)
|
||||
|
||||
return {
|
||||
"code": 0,
|
||||
"message": "查询成功",
|
||||
"data": {
|
||||
"id": open_type.id,
|
||||
"type_name": open_type.type_name,
|
||||
"open_type": open_type.open_type,
|
||||
"description": open_type.description,
|
||||
"thumb": open_type.thumb,
|
||||
"created_at": open_type.created_at,
|
||||
"updated_at": open_type.updated_at,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@router.post(
|
||||
"/",
|
||||
summary="创建开户方式",
|
||||
description="创建新的开户方式",
|
||||
response_model=OpenTypeResponse,
|
||||
)
|
||||
async def create_open_type(
|
||||
req: OpenTypeCreate = Body(...),
|
||||
admin: User = Depends(get_admin_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
) -> Any | dict:
|
||||
existing = await db.execute(
|
||||
select(OpenType).where(OpenType.open_type == req.open_type, OpenType.deleted_at.is_(None))
|
||||
)
|
||||
if existing.scalar_one_or_none():
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=f"开户方式ID {req.open_type} 已存在",
|
||||
)
|
||||
|
||||
open_type = OpenType(
|
||||
id=generate_id(),
|
||||
type_name=req.type_name,
|
||||
open_type=req.open_type,
|
||||
description=req.description,
|
||||
thumb=req.thumb,
|
||||
)
|
||||
|
||||
db.add(open_type)
|
||||
await db.commit()
|
||||
await db.refresh(open_type)
|
||||
|
||||
return {
|
||||
"code": 0,
|
||||
"message": "创建成功",
|
||||
"data": {
|
||||
"id": open_type.id,
|
||||
"type_name": open_type.type_name,
|
||||
"open_type": open_type.open_type,
|
||||
"description": open_type.description,
|
||||
"thumb": open_type.thumb,
|
||||
"created_at": open_type.created_at,
|
||||
"updated_at": open_type.updated_at,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@router.put(
|
||||
"/{id}",
|
||||
summary="更新开户方式",
|
||||
description="更新指定的开户方式",
|
||||
response_model=OpenTypeResponse,
|
||||
)
|
||||
async def update_open_type(
|
||||
id: str,
|
||||
req: OpenTypeUpdate = Body(...),
|
||||
admin: User = Depends(get_admin_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
) -> Any | dict:
|
||||
result = await db.execute(
|
||||
select(OpenType).where(OpenType.id == id, OpenType.deleted_at.is_(None))
|
||||
)
|
||||
open_type = result.scalar_one_or_none()
|
||||
|
||||
if not open_type:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="开户方式不存在",
|
||||
)
|
||||
|
||||
if req.open_type is not None and req.open_type != open_type.open_type:
|
||||
existing = await db.execute(
|
||||
select(OpenType).where(
|
||||
OpenType.open_type == req.open_type,
|
||||
OpenType.id != id,
|
||||
OpenType.deleted_at.is_(None),
|
||||
)
|
||||
)
|
||||
if existing.scalar_one_or_none():
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=f"开户方式ID {req.open_type} 已存在",
|
||||
)
|
||||
|
||||
if req.type_name is not None:
|
||||
open_type.type_name = req.type_name
|
||||
if req.open_type is not None:
|
||||
open_type.open_type = req.open_type
|
||||
if req.description is not None:
|
||||
open_type.description = req.description
|
||||
if req.thumb is not None:
|
||||
open_type.thumb = req.thumb
|
||||
|
||||
await db.commit()
|
||||
await db.refresh(open_type)
|
||||
|
||||
return {
|
||||
"code": 0,
|
||||
"message": "更新成功",
|
||||
"data": {
|
||||
"id": open_type.id,
|
||||
"type_name": open_type.type_name,
|
||||
"open_type": open_type.open_type,
|
||||
"description": open_type.description,
|
||||
"thumb": open_type.thumb,
|
||||
"created_at": open_type.created_at,
|
||||
"updated_at": open_type.updated_at,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@router.delete(
|
||||
"/{id}",
|
||||
summary="删除开户方式",
|
||||
description="软删除指定的开户方式",
|
||||
response_model=OpenTypeResponse,
|
||||
)
|
||||
async def delete_open_type(
|
||||
id: str,
|
||||
admin: User = Depends(get_admin_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
) -> Any | dict:
|
||||
result = await db.execute(
|
||||
select(OpenType).where(OpenType.id == id, OpenType.deleted_at.is_(None))
|
||||
)
|
||||
open_type = result.scalar_one_or_none()
|
||||
|
||||
if not open_type:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="开户方式不存在",
|
||||
)
|
||||
|
||||
open_type.deleted_at = func.now()
|
||||
await db.commit()
|
||||
|
||||
return {
|
||||
"code": 0,
|
||||
"message": "删除成功",
|
||||
"data": None,
|
||||
}
|
||||
@@ -222,6 +222,14 @@ async def async_batch_upload_material(
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
) -> Any | dict:
|
||||
|
||||
# param = {
|
||||
# "account_ids" : json.dumps([1836693172153543]),
|
||||
# }
|
||||
|
||||
# account_info = await DouyinApi().get_account_info("0019eb9f130027c05b8", param)
|
||||
# return account_info
|
||||
|
||||
if not req.tasks:
|
||||
return {
|
||||
"code": 0,
|
||||
|
||||
Reference in New Issue
Block a user