完成定时任务分润。

This commit is contained in:
aaron 2025-03-12 22:48:08 +08:00
parent 4b07324516
commit a52e44705d
5 changed files with 178 additions and 4 deletions

View File

@ -233,7 +233,8 @@ async def create_order(
# 是否为新人订单 # 是否为新人订单
is_first_order = db.query(ShippingOrderDB).filter( is_first_order = db.query(ShippingOrderDB).filter(
ShippingOrderDB.userid == current_user.userid ShippingOrderDB.userid == current_user.userid,
ShippingOrderDB.status != OrderStatus.CANCELLED
).count() == 0 ).count() == 0
# 创建订单 # 创建订单

View File

@ -14,7 +14,7 @@ from app.models.community_set_mapping import CommunitySetMapping
from app.models.community_set import CommunitySet from app.models.community_set import CommunitySet
from app.models.order import ShippingOrderDB, OrderStatus from app.models.order import ShippingOrderDB, OrderStatus
from app.models.community import CommunityDB from app.models.community import CommunityDB
from app.models.address import AddressDB
router = APIRouter() router = APIRouter()
@router.get("/summary", response_model=ResponseModel) @router.get("/summary", response_model=ResponseModel)
@ -90,7 +90,6 @@ async def partner_summary(
"today_order_amount": 0 if today_income is None else today_income, "today_order_amount": 0 if today_income is None else today_income,
"yesterday_order_amount": 0 if yesterday_income is None else yesterday_income}) "yesterday_order_amount": 0 if yesterday_income is None else yesterday_income})
@router.get("/community_list", response_model=ResponseModel) @router.get("/community_list", response_model=ResponseModel)
async def partner_community_list( async def partner_community_list(
db: Session = Depends(get_db), db: Session = Depends(get_db),
@ -123,6 +122,12 @@ async def partner_community_list(
for community_id in community_ids: for community_id in community_ids:
community = db.query(CommunityDB).filter(CommunityDB.id == community_id).first() community = db.query(CommunityDB).filter(CommunityDB.id == community_id).first()
# 根据地址获取当前小区的用户量
user_count = db.query(AddressDB).filter(
AddressDB.community_id == community_id,
AddressDB.is_default == True
).count()
# 获取今日、昨日订单量 # 获取今日、昨日订单量
today_start = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) today_start = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
today_end = datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999) today_end = datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
@ -161,6 +166,7 @@ async def partner_community_list(
results.append({ results.append({
"community_id": community_id, "community_id": community_id,
"community_name": community.name, "community_name": community.name,
"user_count": user_count,
"today_order_count": today_order_count, "today_order_count": today_order_count,
"yesterday_order_count": yesterday_order_count, "yesterday_order_count": yesterday_order_count,
"today_income": 0 if today_income is None else today_income, "today_income": 0 if today_income is None else today_income,
@ -168,3 +174,6 @@ async def partner_community_list(
}) })
return success_response(data={"items": results, "total": total_count}) return success_response(data={"items": results, "total": total_count})

View File

@ -8,6 +8,7 @@ class Settings(BaseSettings):
API_V1_STR: str = "/api/v1" API_V1_STR: str = "/api/v1"
PROJECT_NAME: str = "FastAPI 项目" PROJECT_NAME: str = "FastAPI 项目"
ENV_NAME: str = "开发环境" ENV_NAME: str = "开发环境"
PLATFORM_USER_ID: int = 9
API_BASE_URL: str = "https://api-dev.beefast.co" API_BASE_URL: str = "https://api-dev.beefast.co"
@ -126,6 +127,7 @@ class DevSettings(Settings):
API_V1_STR: str = "/api/v1" API_V1_STR: str = "/api/v1"
PROJECT_NAME: str = "FastAPI 项目 (测试环境)" PROJECT_NAME: str = "FastAPI 项目 (测试环境)"
ENV_NAME: str = "测试环境" ENV_NAME: str = "测试环境"
PLATFORM_USER_ID: int = 9
API_BASE_URL: str = "https://api-dev.beefast.co" API_BASE_URL: str = "https://api-dev.beefast.co"
@ -153,7 +155,7 @@ class ProdSettings(Settings):
PROJECT_NAME: str = "FastAPI 项目 (生产环境)" PROJECT_NAME: str = "FastAPI 项目 (生产环境)"
ENV_NAME: str = "生产环境" ENV_NAME: str = "生产环境"
API_BASE_URL: str = "https://api.beefast.co" API_BASE_URL: str = "https://api.beefast.co"
PLATFORM_USER_ID: int = 45
# 数据库配置 # 数据库配置
MYSQL_HOST: str = "cd-cynosdbmysql-grp-7kdd8qe4.sql.tencentcdb.com" MYSQL_HOST: str = "cd-cynosdbmysql-grp-7kdd8qe4.sql.tencentcdb.com"
MYSQL_PORT: int = 26558 MYSQL_PORT: int = 26558

View File

@ -11,6 +11,10 @@ from app.core.config import settings
from app.models.statistics import DailyCommunityOrderStats, DailyOrderStats from app.models.statistics import DailyCommunityOrderStats, DailyOrderStats
from sqlalchemy.exc import IntegrityError from sqlalchemy.exc import IntegrityError
from app.models.community import CommunityDB from app.models.community import CommunityDB
from app.models.user import UserDB, UserRole
from app.models.community_set import CommunitySet
from app.models.community_set_mapping import CommunitySetMapping
from app.core.account import AccountManager
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -212,6 +216,157 @@ def run_daily_community_order_statistics():
except Exception as e: except Exception as e:
logger.error(f"运行每日小区订单统计任务失败: {str(e)}") logger.error(f"运行每日小区订单统计任务失败: {str(e)}")
async def daily_partner_settlement():
"""每日合伙人结算任务"""
logger.info(f"开始执行每日合伙人结算任务: {datetime.now()}")
with get_db_context() as db:
try:
# 获取昨日订单统计数据
yesterday = (datetime.now() - timedelta(days=1)).date()
yesterday_stats = db.query(DailyCommunityOrderStats).filter(
DailyCommunityOrderStats.stats_date == yesterday
).all()
if not yesterday_stats:
logger.info(f"昨日没有订单统计数据,跳过结算")
return
# 遍历每个小区的订单统计数据
total_partner_profit = 0
total_admin_profit = 0
total_delivery_profit = 0
total_platform_profit = 0
total_order_count = 0
total_original_amount = 0
total_final_amount = 0
for stat in yesterday_stats:
print(stat.community_name)
total_order_count += stat.order_count
total_original_amount += stat.total_original_amount
total_final_amount += stat.total_final_amount
community = db.query(CommunityDB).filter(
CommunityDB.id == stat.community_id
).first()
# 找到所有的运营商
community_sets = db.query(CommunitySet).filter(
CommunitySet.community_set_mappings.any(
CommunitySetMapping.community_id == stat.community_id
)
).all()
# 提取运营商列表
partner_ids = []
for sets in community_sets:
if sets.user_id and sets.user_id not in partner_ids:
partner_ids.append(sets.user_id)
# 获取分成比例
admin_profit_sharing = community.community_profit_sharing.admin_rate
partner_profit_sharing = community.community_profit_sharing.partner_rate
delivery_profit_sharing = community.community_profit_sharing.delivery_rate
platform_profit_sharing = community.community_profit_sharing.platform_rate
# 计算运营商分成金额
per_partner_profit = stat.total_final_amount * (float(partner_profit_sharing) / len(partner_ids)) / 100
# 计算每个运营商的分成金额
print(f"小区 {stat.community_name} 分成比例:{partner_profit_sharing} %,累计收益: {stat.total_final_amount}")
for partner_id in partner_ids:
partner_profit = per_partner_profit
print(f"运营商 {partner_id} 分成金额: {partner_profit}")
total_partner_profit += partner_profit
# 更新运营商账户余额
if partner_profit > 0:
account_manager = AccountManager(db)
account_manager.change_balance(partner_id, partner_profit, f"{stat.community_name} 订单收益")
# 计算服务商分成
admin_profit = stat.total_final_amount * (float(admin_profit_sharing) / 100)
print(f"服务商分成金额: {admin_profit}")
total_admin_profit += admin_profit
if admin_profit > 0 and community.admin_id and community.admin_id > 0:
account_manager = AccountManager(db)
account_manager.change_balance(community.admin_id, admin_profit, f"{stat.community_name} 订单收益")
# 计算配送员分成
delivery_profit = stat.total_final_amount * (float(delivery_profit_sharing) / 100)
print(f"配送员分成金额: {delivery_profit}")
total_delivery_profit += delivery_profit
# if delivery_profit > 0:
# account_manager = AccountManager(db)
# account_manager.change_balance(community.admin_id, delivery_profit, f"{stat.community_name} 订单收益")
# 计算平台分成
platform_profit = stat.total_final_amount * (float(platform_profit_sharing) / 100)
print(f"平台分成金额: {platform_profit}")
total_platform_profit += platform_profit
if platform_profit > 0:
account_manager = AccountManager(db)
account_manager.change_balance(settings.PLATFORM_USER_ID, platform_profit, f"{stat.community_name} 订单收益")
# 生成分润报告
message = f"""### {yesterday.strftime("%Y-%m-%d")} 分润报告
**环境{settings.ENV_NAME}**
### 订单汇总
> - 订单总数: {total_order_count}
> - 订单总金额: {total_original_amount:.1f}
> - 支付总金额: {total_final_amount:.1f}
### 分润汇总
> - 合伙人分成: {total_partner_profit:.1f}
> - 服务商分成: {total_admin_profit:.1f}
> - 配送员分成: {total_delivery_profit:.1f}
> - 平台分成: {total_platform_profit:.1f}
"""
# 发送企业微信消息
if total_partner_profit + total_admin_profit + total_delivery_profit + total_platform_profit > 0 and settings.URL_WECOMBOT_DAILY_REPORT:
try:
wecom_bot = WecomBot(settings.URL_WECOMBOT_DAILY_REPORT)
await wecom_bot.send_markdown(message)
logger.info("每日合伙人结算报告已发送到企业微信")
except Exception as e:
logger.error(f"发送企业微信消息失败: {str(e)}")
except Exception as e:
db.rollback()
logger.error(f"运行每日合伙人结算任务失败: {str(e)}")
def run_daily_partner_settlement():
"""
包装异步函数的同步函数用于APScheduler调度
"""
try:
# 获取或创建事件循环
try:
loop = asyncio.get_event_loop()
except RuntimeError:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
# 运行异步任务
if loop.is_running():
future = asyncio.ensure_future(daily_partner_settlement())
future.add_done_callback(lambda f: logger.info("每日合伙人结算任务完成"))
else:
loop.run_until_complete(daily_partner_settlement())
except Exception as e:
logger.error(f"运行每日合伙人结算任务失败: {str(e)}")
def register_daily_tasks(): def register_daily_tasks():
"""注册所有每日定时任务""" """注册所有每日定时任务"""
@ -224,4 +379,11 @@ def register_daily_tasks():
job_id="daily_community_order_stats" job_id="daily_community_order_stats"
) )
scheduler.add_cron_job(
run_daily_partner_settlement,
hour=8,
minute=0,
job_id="daily_partner_settlement"
)
logger.info("已注册所有每日定时任务") logger.info("已注册所有每日定时任务")

Binary file not shown.